List reviews
GET/api/v1/reviews
scope
reviews:readPaginatedLists the ratings and answers customers have submitted, newest first, with cursor pagination. Filter by form, contact or star range, or pass alerts=open for the low ratings nobody has acknowledged yet. A review left through a form’s walk-in link has no contact.
Query parameters
| Name | Type | Description |
|---|---|---|
limitoptional | integer | Page size, 1–100Default: 20 |
cursoroptional | string | The `next_cursor` from the previous page |
form_idoptional | string (uuid) | Only reviews submitted on this form |
contact_idoptional | string (uuid) | Only this contact’s reviews |
min_starsoptional | integer | At least this many stars |
max_starsoptional | integer | At most this many stars |
alertsoptional | string (enum) | `open` returns only low ratings that have not been acknowledgedopen |
created_sinceoptional | string (date-time) | Only reviews submitted at or after this time |
Request
curl "https://your-crm.example.com/api/v1/reviews?limit=20&min_stars=4" \
-H "Authorization: Bearer $RAABTA_API_KEY"Response · 200 OK
{
"data": [
{
"id": "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b",
"request_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"contact_id": "9d7e4c11-5a2b-4f7c-8e3d-2a1b0c9d8e7f",
"form_id": "f0a1b2c3-d4e5-4f6a-8b7c-9d0e1f2a3b4c",
"form_name": "After-visit feedback",
"stars": 5,
"answers": [
{
"question_id": "q1",
"type": "text",
"label": "What could we do better?",
"value": "Nothing — the team was great."
}
],
"gate_passed": true,
"is_alert": false,
"alert_acknowledged_at": null,
"created_at": "2026-09-02T12:30:00.000Z"
}
],
"meta": {
"next_cursor": null,
"has_more": false,
"limit": 20
}
}Response
Wrapped in { data: [...], meta }| Name | Type | Description |
|---|---|---|
idrequired | string (uuid) | UUID |
request_idrequired | string (uuid) | null | The request it answers; null for a walk-in review |
contact_idrequired | string (uuid) | null | Who left it; null for an anonymous walk-in review |
form_idrequired | string (uuid) | null | The form it was submitted on |
form_namerequired | string | null | The form’s name when the review was submitted |
starsrequired | integer | The rating, 0 to 5 |
answersrequired | object[] | The customer’s answers, with each question as it read at the time |
answers[].question_idrequired | string | The question’s id on the form |
answers[].typerequired | string (enum) | The kind of questiontextscaleyes_no |
answers[].labelrequired | string | The question as the customer saw it |
answers[].valuerequired | string | number | boolean | What they answered |
gate_passedrequired | boolean | True when the rating met the account’s threshold, so the customer was shown the public review platforms |
is_alertrequired | boolean | True for a low rating that was kept private and flagged for the team |
alert_acknowledged_atrequired | string (date-time) | null | When a member acknowledged the alert |
created_atrequired | string (date-time) | ISO 8601 timestamp |
Errors
| Status | Code | When |
|---|---|---|
| 400 | bad_request | The request could not be parsed: malformed JSON, an invalid cursor, or a query parameter of the wrong shape. |
| 400 | validation_error | The body or query failed validation. `details` lists each failing field with a `path` and a `message`. |
| 401 | unauthorized | No usable API key: the Authorization header is missing or malformed, or the key is unknown, revoked or expired. The three are deliberately indistinguishable. |
| 403 | forbidden | The key is valid but lacks the scope this endpoint requires, or the request came from an address outside the key’s IP allowlist. The message says which. |
| 403 | account_suspended | The account this key belongs to is suspended. Rotating the key will not help; contact support. |
| 429 | rate_limited | The per-key budget, or the per-IP budget for failed authentication, is exhausted. Honour `Retry-After` before retrying. |
| 500 | internal | Something failed on our side. Safe to retry with the same Idempotency-Key; quote `request_id` if it persists. |