https://rapi.trustoo.io⚠️ Important Update (November 2025) We have upgraded our signature algorithm from SHA-256 with salt to HMAC-SHA256 for enhanced security and better cross-platform compatibility. Key Changes: ✅ More secure authentication using industry-standard HMAC ✅ JSON key order no longer affects signature ✅ Compatible with major platforms like Shopify and Stripe ⚠️ Breaking Change: Old signatures are no longer valid Migration Required: All existing integrations must update their signature generation code. See Section 2.2 for updated implementation examples in all languages.
| Method | Headers | Use Case |
|---|---|---|
| HMAC Signature | Public-Token, Sign, Timestamp | Shop owners integrating directly |
| OAuth 2.0 Bearer Token | Authorization: Bearer <access_token> | Third-party platforms integrating on behalf of merchants |
Authorization header is present and non-empty, OAuth 2.0 Bearer Token is attempted. Otherwise, HMAC Signature authentication is used.| Endpoint | Description | Authentication |
|---|---|---|
GET /api/v1/openapi/get_open_api_information | Retrieve the shop's Public Token | JWT (shop merchant session) |
GET /api/v1/openapi/get_open_api_private_token | Retrieve the shop's Private Token | JWT (shop merchant session) |
⚠️ After a reset, the original private token becomes immediately invalid. Update all authorized third-party applications with the new token.
| Header | Description | Example |
|---|---|---|
Public-Token | Your shop's public token | GfKu22TCaj4gULtrA3/OgA== |
timestamp | Current Unix timestamp (seconds) | 1700465771 |
sign | HMAC-SHA256 signature (lowercase hex) | c3f6910a4dc12969c819f47621e5adf... |
⚠️ The timestamp is valid for 15 minutes only. Regenerate it for each request.
client_id, client_secret, and a webhook_url (see System Webhooks)redirect_uriaccess_token and refresh_tokenAuthorization: Bearer <access_token>POST /api/v1/openapi/oauth/disconnect to revoke the platform's authorization for a shop| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_oauth_authorize_url | GET | Get the one-click authorization URL for merchants |
/api/v1/openapi/oauth/authorize | GET | Merchant-facing authorization page (validates and redirects with code) |
/api/v1/openapi/oauth/token | POST | Exchange authorization_code or refresh_token for tokens |
/api/v1/openapi/oauth_revoke_token | POST | Revoke an access or refresh token |
access_token — 1 hourrefresh_token — 30 dayswebhook_url when OAuth lifecycle events occur. These events do not require a subscription — they are always delivered.| Event | Trigger | Description |
|---|---|---|
app/authorized | OAuth flow completed | A merchant successfully authorized your platform |
integration/disconnected | Platform disconnected | A platform's authorization for a shop was revoked (via oauth/disconnect or cancel_authorization) |
app/uninstalled | Trustoo app uninstalled | A merchant uninstalled the Trustoo app from their Shopify store (all platform authorizations are revoked) |
{
"event": "app/authorized",
"shop_id": 59730165893,
"platform": "instafeed",
"timestamp": 1732180800
}| Field | Type | Description |
|---|---|---|
event | string | Event type: app/authorized, integration/disconnected, or app/uninstalled |
shop_id | integer | Shopify shop ID (numeric) |
platform | string | Platform client_id |
timestamp | integer | Event timestamp (Unix epoch seconds) |
X-Trustoo-Signature header:| Header | Description |
|---|---|
X-Trustoo-Signature | HMAC-SHA256 signature (lowercase hex) |
HMAC-SHA256(platform_secret, raw_request_body) → compare with X-Trustoo-Signatureplatform_secret is the client_secret you received during platform registrationX-Trustoo-Signature header⚠️ Difference from Shop Webhooks: Shop webhooks (Section 3.5) use Open-Trustoo-Webhook-Sign+Public-Tokenfor HMAC authentication. System webhooks useX-Trustoo-Signaturesigned with your platform'sclient_secret.
| Scope | Description | Includes |
|---|---|---|
read_reviews | Read reviews and ratings | — |
write_reviews | Create and delete reviews, manage webhooks | read_reviews |
read_orders | Read order history | — |
read_customer_events | Read customer interaction events | — |
read_customers | Read customer exclusion list | — |
write_customers | Manage customer exclusions and unsubscribes | read_customers |
read_shop_install_status | Check shop installation status | — |
Write scopes automatically include the corresponding read scope (following Shopify convention).
| Webhook Topic | Required Scope |
|---|---|
review/created | write_reviews |
review/updated | write_reviews |
review/deleted | write_reviews |
customer_event/created | read_customer_events |
timestampkey1=value1&key2=value2&...| separatorGET /api/v1/openapi/get_reviewsproduct_ids=9228589138176
page_size=20
page=1product_ids=9228589138176&page_size=20&page=1×tamp=1732180800page=1&page_size=20&product_ids=9228589138176×tamp=1732180800HMAC-SHA256("page=1&page_size=20&product_ids=9228589138176×tamp=1732180800", private_token)
→ c3648110bc3f1f63e7ed54fc4390448bfd2a131b405aeed91cd26a42b3ee9a93POST /api/v1/openapi/create_shop_webhook{"topic":"review/created","url":"https://your-webhook-url.com"}timestamp=1732180800| + body):timestamp=1732180800|{"topic":"review/created","url":"https://your-webhook-url.com"}HMAC-SHA256("timestamp=1732180800|{\"topic\":\"review/created\",\"url\":\"https://your-webhook-url.com\"}", private_token)
→ ee5d60dd3fbc3c70e49405564f4830466a11382f088eb127c5c5237c5c9b3e91Important Notes: Use the exact JSON string you're sending — do not parse and re-serialize JSON key order doesn't matter because we use the raw string The |separator is used between parameters and body
| Type | Subscription Required | Events | Section |
|---|---|---|---|
| Subscription Webhooks | Yes — subscribe via create_shop_webhook | review/created, review/updated, review/deleted, customer_event/created | Below |
| System Webhooks | No — always delivered to your platform's registered webhook_url | app/authorized, integration/disconnected, app/uninstalled | 1.3 OAuth Lifecycle Webhooks |
⚠️ System webhooks use a different signing method ( X-Trustoo-Signaturesigned with yourclient_secret). Subscription webhooks useOpen-Trustoo-Webhook-Sign+Public-Token. See the respective sections for verification details.
{
"code": 0,
"message": "success"
}⚠️ The HTTP status code must be 200. Any other status code is treated as a failure and will trigger a retry.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/create_shop_webhook | POST | Register a new webhook subscription |
/api/v1/openapi/update_shop_webhook | POST | Update an existing webhook's URL |
/api/v1/openapi/delete_shop_webhook | POST | Delete a webhook subscription |
/api/v1/openapi/get_shop_webhooks | GET | List all webhook subscriptions |
Webhooks are scoped to the authenticated shop or platform. Platform isolation ensures each platform only receives events for its authorized shops.
| Attempt | Delay (min) | Cumulative (min) |
|---|---|---|
| 1 | 0 | 0 |
| 2 | 3 | 3 |
| 3 | 6 | 9 |
| 4 | 9 | 18 |
| 5 | 12 | 30 |
| 6 | 15 | 45 |
| 7 | 18 | 63 |
| 8 | 21 | 84 |
| 9 | 24 | 108 |
| 10 | 27 | 135 |
| Event Type | Description |
|---|---|
review/created | Triggered when a new review is created |
review/updated | Triggered when an existing review is updated |
review/deleted | Triggered when a review is deleted |
customer_event/created | Triggered when a new customer interaction event occurs |
| Header | Value | Description |
|---|---|---|
Content-Type | application/json | Fixed value |
Open-Trustoo-Webhook-Public-Token | xxxx | Your shop's public token |
Open-Trustoo-Webhook-Timestamp | 1732180800 | Unix timestamp of the request |
Open-Trustoo-Webhook-Sign | a37084ab... | HMAC-SHA256 signature (see Section 2) |
Open-Trustoo-Webhook-RequestId | kfhgdsjk... | Unique request trace ID |
{
"event": "review/created",
"shop_id": "59730165893",
"data": { /* event-specific payload — see below */ }
}| Field | Type | Description |
|---|---|---|
event | string | Event type (see 3.4) |
shop_id | string | The Shopify shop ID |
data | object | Event payload (varies by event type) |
{
"event": "review/created",
"shop_id": "59730165893",
"data": {
"id": "57748",
"rating": 5,
"author": "John Doe",
"author_email": "[email protected]",
"author_phone": "+1234567890",
"author_country": "US",
"title": "Great product!",
"content": "This is an amazing product, highly recommend!",
"commented_at": "2023-11-21T12:34:56Z",
"item_type": "product",
"order_id": "1001",
"variant_id": "789",
"source": "email",
"is_verified": 1,
"is_featured": 0,
"is_published": 1,
"is_top": 0,
"tag": "",
"media_type": 1,
"media": [
{ "url": "https://cdn.example.com/image1.jpg", "thumbnail_url": "https://cdn.example.com/thumb1.jpg", "type": 1, "is_published": 1 },
{ "url": "https://cdn.example.com/video1.mp4", "thumbnail_url": "https://cdn.example.com/thumb2.jpg", "type": 2, "is_published": 1 }
],
"reply": {
"id": "reply_001",
"content": "Thank you for your review!",
"reply_at": "2023-11-22T09:00:00Z"
},
"product": {
"id": "789",
"title": "Awesome Product",
"handle": "awesome-product",
"image_src": "https://cdn.example.com/product.jpg",
"url": "https://example.myshopify.com/products/awesome-product"
},
"created_at": "2023-11-21T12:34:56Z",
"updated_at": "2023-11-21T12:45:00Z"
}
}| Field | Type | Description |
|---|---|---|
id | string | Unique review ID |
rating | integer | Rating 1–5 |
author | string | Reviewer name |
author_email | string | Reviewer email |
author_phone | string | Reviewer phone number |
author_country | string | Country code (ISO 3166-1 alpha-2) |
title | string | Review title |
content | string | Review text |
commented_at | string | Review timestamp (RFC 3339) |
item_type | string | Item type (e.g., product) |
order_id | string | Associated order ID |
variant_id | string | Product variant ID |
source | string | Review source (email, storefront, admin, etc.) |
is_verified | integer | Verified purchase: 1 = Yes, 0 = No |
is_featured | integer | Featured: 1 = Yes, 0 = No |
is_published | integer | Published: 1 = Yes, 0 = No |
is_top | integer | Pinned to top: 1 = Yes, 0 = No |
tag | string | Tag label |
media_type | integer | Media type: 1 = Image, 2 = Video |
media | array | List of attached media objects: url (string), thumbnail_url (string), type (integer: 1=image, 2=video), is_published (integer: 1=Yes, 0=No) |
reply | object | Merchant reply with id, content, reply_at (null if no reply) |
product | object | Associated product info: id, title, handle, image_src, url |
created_at | string | Created timestamp (RFC 3339) |
updated_at | string | Last updated timestamp (RFC 3339) |
{
"event": "review/deleted",
"shop_id": "59730165893",
"data": {
"id": "57853",
"deleted_at": "2026-05-19T06:58:30Z"
}
}| Field | Type | Description |
|---|---|---|
id | string | Deleted review ID |
deleted_at | string | Deletion timestamp (RFC 3339) |
{
"event": "customer_event/created",
"shop_id": "59730165893",
"data": {
"id": "12345",
"client_id": "cli_abc123",
"event_type": "VIEW_REVIEW",
"event_source": "STOREFRONT",
"device_type": "Mobile",
"os_type": "IOS",
"page_url": "https://example.myshopify.com/products/awesome-product",
"created_at": "2023-11-21T14:30:00Z",
"properties": "{\"review_id\":\"57748\",\"product_id\":\"789\"}"
}
}| Field | Type | Description |
|---|---|---|
id | string | Unique event ID |
client_id | string | Client identifier |
event_type | string | Event type: VIEW_REVIEW, EXPAND_CONTENT, SUBMIT_REVIEW, CLICK_REVIEW, etc. |
event_source | string | Source: STOREFRONT, EMAIL, ADMIN |
device_type | string | Device: Desktop, Mobile, Tablet |
os_type | string | Operating system: IOS, ANDROID, WINDOWS, etc. |
page_url | string | Page URL where the event occurred |
created_at | string | Event timestamp (RFC 3339) |
properties | string | JSON string with detailed event information |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/send_test_webhook | POST | Send a simulated webhook event to your registered webhook URL |
{
"topic": "review/created",
"data": {
"id": "99999",
"rating": 5,
"content": "This is a test review"
}
}| Field | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | Event type to simulate. One of: review/created, review/updated, review/deleted, customer_event/created, app/authorized, integration/disconnected, app/uninstalled |
data | object | No | Custom payload data to include. If omitted, a sample payload is used. |
create_shop_webhook (for subscription events) or your platform's registered webhook_url (for system events)Open-Trustoo-Webhook-Sign for subscription events, X-Trustoo-Signature for system events)| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_oauth_authorize_url | GET | Get the one-click authorization URL for merchants |
/api/v1/openapi/oauth/authorize | GET | Merchant-facing authorization page (validates and redirects with code) |
/api/v1/openapi/oauth/token | POST | Exchange authorization_code or refresh_token for tokens |
/api/v1/openapi/oauth_revoke_token | POST | Revoke an access or refresh token |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/create_shop_webhook | POST | Register a new webhook subscription |
/api/v1/openapi/update_shop_webhook | POST | Update an existing webhook's URL |
/api/v1/openapi/delete_shop_webhook | POST | Delete a webhook subscription |
/api/v1/openapi/get_shop_webhooks | GET | List all webhook subscriptions |
/api/v1/openapi/send_test_webhook | POST | Send a simulated webhook event for testing |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_reviews | GET | List reviews with pagination and filters |
/api/v1/openapi/get_review | GET | Get a single review by ID |
/api/v1/openapi/get_rating | GET | Get aggregate rating data |
/api/v1/openapi/create_review | POST | Create a new review |
/api/v1/openapi/delete_review | POST | Delete a review |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_orders | GET | Query order history |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_customer_events | GET | Query customer interaction events |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_customer_excludes | GET | List customer exclusions |
/api/v1/openapi/create_customer_exclude | POST | Add a customer to the exclusion list |
/api/v1/openapi/delete_customer_exclude | POST | Remove a customer from the exclusion list |
/api/v1/openapi/email_unsubscribe | POST | Unsubscribe a customer from emails |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_video_upload_url | GET | Get a pre-signed video upload URL |
/api/v1/openapi/get_image_upload_policy_token | GET | Get an image upload policy token |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/openapi/get_shop_install_status | GET | Check shop installation status |
/api/v1/openapi/get_shop_authorization_info | GET | Get shop authorization details |
/api/v1/openapi/oauth/disconnect | POST | Disconnect (revoke) a platform's authorization |
{
"code": 0,
"reason_code": 0,
"message": "success",
"data": {},
"request_id": "abc123",
"time": 1732180800
}| Field | Type | Description |
|---|---|---|
code | integer | 0 = success, non-zero = error (gRPC status code) |
reason_code | integer | gRPC status code for programmatic handling |
message | string | User-facing error description |
data | object | Response payload (null on error) |
request_id | string | Unique request trace ID |
time | integer | Server timestamp (Unix epoch seconds) |
| Code | Status | Message | Description |
|---|---|---|---|
| 0 | OK | success | Request succeeded |
| 1 | Canceled | Sorry, something went wrong. Please try again later. | Operation was canceled |
| 2 | Unknown | Sorry, something went wrong. Please try again later. | Unknown error |
| 3 | InvalidArgument | Sorry, parameter error. | Client specified an invalid argument |
| 4 | DeadlineExceeded | Sorry, the server is busy. Please try again later. | Deadline expired (e.g., HMAC timestamp > 15 min) |
| 5 | NotFound | Sorry, data not found. | Requested entity not found (e.g., shop, review) |
| 6 | AlreadyExists | Sorry, data already exists. | Entity already exists (e.g., duplicate webhook) |
| 7 | PermissionDenied | Sorry, no permission. | Insufficient OAuth scope or shop not authorized |
| 8 | ResourceExhausted | — | Operation was rejected due to resource limits |
| 11 | OutOfRange | Sorry, data size too large. | Data exceeds size limits |
| 13 | Internal | — | Internal server error |
| 16 | Unauthenticated | Sorry, authentication failed. | Invalid signature, expired token, or missing credentials |
| Scenario | Code | Fix |
|---|---|---|
| HMAC timestamp expired | 4 | Ensure your server clock is synchronized and the timestamp is within 15 minutes |
| HMAC signature mismatch | 16 | Verify signature computation: HMAC-SHA256(privateToken, sortedParams + | + body) |
| OAuth access token expired | 16 | Use refresh_token to obtain a new access_token |
| Insufficient OAuth scope | 7 | Re-authorize the merchant with the required scopes via /oauth/authorize |
| Shop not authorized for platform | 7 | The merchant needs to complete the OAuth authorization flow |
| Shop granted scopes changed | 7 | The merchant's granted scopes have been modified; re-authorization is needed |
| Invalid parameters | 3 | Check required fields and parameter formats |
| Webhook topic not supported | 3 | Use a valid topic: review/created, review/updated, review/deleted, customer_event/created |
Default module.openapi.json — Complete OpenAPI 3.0.3 specification