Review Collect API
Programmatic access to the data of your Review Collect account, from your own tools, warehouse or scripts.
Introduction
The API is organised around resources. Each resource has its own section below with its object definition and endpoints. Requests go over HTTPS and responses are JSON.
Authentication
Every request carries your API key in the X-Api-Key header. A key is bound to one Review Collect account. Request yours from your account manager and keep it server side, never in a browser or a mobile app.
curl "https://api.review-collect.com/api:v1/invitations?limit=100" \
-H "X-Api-Key: $RC_API_KEY"A missing or unknown key returns 401, a key of an inactive account returns 403.
Pagination
List endpoints share one envelope and two parameters: limit, 1 to 1000 objects per page, and cursor, the next_cursor of the previous page.
{
"object": "list",
"data": [ … ],
"has_more": true,
"next_cursor": "8448610"
}
Call again with cursor while has_more is true. The cursor is the last id of the page, so a walk stays consistent while new objects are being created. The same filters apply to every page.
Errors
Errors use HTTP status codes and a JSON body with a readable message.
| Status | Code | When |
|---|---|---|
| 400 | ERROR_CODE_BAD_REQUEST | A query parameter is invalid. The message names it. |
| 401 | ERROR_CODE_UNAUTHORIZED | Missing or unknown API key. |
| 403 | ERROR_CODE_ACCESS_DENIED | The account is inactive. |
| 404 | ERROR_CODE_NOT_FOUND | Unknown path or resource. |
Example
{ "code": "ERROR_CODE_BAD_REQUEST", "message": "limit must be an integer between 1 and 1000." }
The invitation object
Everything that happened to one customer for one order: the messages sent, the customer's feedback and the review that followed.
| Field | Type | Description |
|---|---|---|
| id | string | Unique, increasing. Used as the pagination cursor. |
| status | string | sent at least one message went out, clicked the customer opened the review page, reviewed a rating was left. |
| source | string | Store integration, file batch (gsheets, sftp, aws_s3), qr_code or api. |
| qr_code | object, nullable | id and name of the scanned QR code. |
| customer | object | name, email, phone (E.164), country (ISO 3166-1), language (ISO 639-1). Each may be null. |
| order | object, nullable | id in the store, number as shown to the customer, created_at, products[] with external_id and title. Null when the contact has no order. |
| location | object, nullable | Point of sale, for multi-location accounts: location_id, location_name. |
| messages | array | Messages actually sent, in order. Each has step (initial, reminder_1, reminder_2, reminder_3), channel and sent_at. |
| sent_at | datetime | Date of the initial message. |
| clicked_at | datetime, nullable | First opening of the review page. |
| review | object, nullable | rating 1 to 5, comment, submitted_at. Null until the customer rates. |
| routing | object, nullable | What followed the feedback, as configured in your Review Routing settings. Null until the customer rates. Detailed below. |
| created_at | datetime | Creation of the invitation. |
| updated_at | datetime | Latest event on the invitation. Drives the since filter. |
Routing
| Field | Type | Description |
|---|---|---|
| type | string | redirect the customer was taken to a public review page, notification you were notified, help_page, none. |
| destination | string, nullable | Redirect: trustpilot, google, judge_me, app_store, google_play, custom_url, indeed, glassdoor, poulpeo. Notification: email, sms, slack, zendesk, gorgias, crisp. |
| published | boolean, nullable | Trustpilot only. true the review was found on Trustpilot, false not found so far, null not applicable or no Trustpilot API connection on the account. |
| published_review | object, nullable | The Trustpilot review once found: id, rating, title, text, url, published_at, plus your reply and replied_at. |
Accounts with the Trustpilot API connected only. Trustpilot reviews are synced daily and attached to the invitation whose customer email matches, dated on or after the redirect. The sync can lag up to 24 hours, and a customer who reviews with another email address is not matched. Without the Trustpilot API connection, and for Google, which does not expose reviewer emails, published stays null.
Full example
{
"object": "invitation",
"id": "8448604",
"status": "reviewed",
"source": "shopify",
"qr_code": null,
"customer": { "name": "Marie Dupont", "email": "marie@example.com", "phone": null, "country": "FR", "language": "fr" },
"order": {
"id": "6507661234",
"number": "650766",
"created_at": "2026-07-25T14:31:32Z",
"products": [ { "external_id": "sku-e3-1", "title": "Matelas 140x190" } ]
},
"location": null,
"messages": [
{ "step": "initial", "channel": "whatsapp", "sent_at": "2026-07-28T14:34:43Z" },
{ "step": "reminder_1", "channel": "email", "sent_at": "2026-07-30T09:00:00Z" }
],
"sent_at": "2026-07-28T14:34:43Z",
"clicked_at": "2026-07-28T14:36:00Z",
"review": { "rating": 5, "comment": "Livraison rapide, matelas top.", "submitted_at": "2026-07-28T14:36:00Z" },
"routing": {
"type": "redirect",
"destination": "trustpilot",
"published": true,
"published_review": {
"id": "68a1f2c3d4e5f60012ab34cd",
"rating": 5,
"title": "Très bon matelas",
"text": "Livraison rapide, matelas très confortable.",
"url": "https://fr.trustpilot.com/reviews/68a1f2c3d4e5f60012ab34cd",
"published_at": "2026-07-29",
"reply": "Merci Marie !",
"replied_at": "2026-07-30"
}
},
"created_at": "2026-07-28T14:34:43Z",
"updated_at": "2026-07-30T06:12:00Z"
}
List invitations
Returns the invitations of the account, one per customer contacted for an order, or per contact for file batches and QR codes, sorted by id ascending.
Query parameters
All optional, combinable.
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Objects per page, 1 to 1000. Default 100. |
| cursor | string | The next_cursor of the previous page. |
| since | datetime | Invitations updated on or after this instant. For incremental loads. |
| from | datetime | Invitations sent on or after this instant. |
| to | datetime | Invitations sent strictly before this instant. |
| status | string | sent, clicked, reviewed |
| channel | string | Channel of the initial message. email, sms, whatsapp |
| source | string | shopify, prestashop, woocommerce, magento, salesforce, hubspot, gsheets, sftp, aws_s3, qr_code, api |
| rating | integer | Rating left on Review Collect, 1 to 5. |
| order_number | string | Exact order number as shown in the store. |
Response
{
"object": "list",
"has_more": true,
"next_cursor": "8448610",
"data": [
{
"object": "invitation",
"id": "8448604",
"status": "reviewed",
"source": "shopify",
"sent_at": "2026-07-28T14:34:43Z",
"review": {
"rating": 5,
"comment": "Livraison rapide, matelas top.",
"submitted_at": "2026-07-28T14:36:00Z"
},
"routing": {
"type": "redirect",
"destination": "trustpilot",
"published": true,
"published_review": { … }
},
…
}
]
}
Each item is an invitation object. Paginate as described in Pagination.
Incremental sync
Load the full history once: walk the pages with limit=1000 until has_more is false. A history of 100,000 invitations loads in about 100 calls.
Then load only what changed with since, which filters on updated_at: an invitation sent in April that gets rated in October comes back in October's delta. Store the instant your run started, pass it as since on the next run, upsert on id. Use from and to for reporting by sending date.