Reviews API errors and how to fix them
Prisma returns one error format for every endpoint and every platform. Each error has an HTTP status, a stable code, a retryable flag and a request_id. Most errors you’ll see in production are one of three things: a connection that needs reauthorization, the per-key rate limit, or a reply the platform won’t take.
Error format
{
"error": {
"type": "conflict_error",
"code": "connection_reauth_required",
"message": "The connection for this location is not active. Reconnect it and try again.",
"retryable": false,
"request_id": "req_01KJ8T3C5D7E9F1G3H5J7K9M1N",
"docs_url": "https://prismareviews.com/docs/errors#connection_reauth_required",
"connection_id": "con_01KJ8P7R5S3T1V9W7X5Y3Z1A2B"
}
}| Field | Description |
|---|---|
type | The family of the error, from the HTTP status (table below). |
code | Stable, machine-readable code. Branch on this, not on message. |
message | Human-readable explanation. It can change; don’t parse it. |
retryable | true for 429 and 5xx errors: the same request can succeed later. |
request_id | The req_… ID, also in the Request-Id header. Log it and include it when you contact support. |
docs_url | Link to the description of this code on this page: https://prismareviews.com/docs/errors#<code>. |
Some errors add fields: max_length and platform on reply_too_long, platform and url on reply_not_supported, platform on plan_upgrade_required, connection_id on connection_reauth_required.
type | HTTP status |
|---|---|
authentication_error | 401 |
permission_error | 403 |
not_found_error | 404 |
conflict_error | 409 |
invalid_request_error | 422 |
rate_limit_error | 429 |
api_error | 500, 501 |
All error codes
| HTTP | code | Retryable | Meaning |
|---|---|---|---|
| 401 | missing_api_key | No | No API key, or not shaped like one. |
| 401 | invalid_api_key | No | The key doesn’t exist or was revoked. |
| 403 | plan_upgrade_required | No | The platform isn’t in your plan. |
| 404 | resource_not_found | No | No object with that ID in your workspace and mode. |
| 404 | reply_not_found | No | The review has no reply to delete. |
| 404 | route_not_found | No | The method and path don’t exist. |
| 409 | connection_reauth_required | No | The location’s connection is not active. |
| 409 | idempotency_conflict | No | The Idempotency-Key was used with a different request. |
| 422 | invalid_request | No | A parameter or the body is missing or invalid. |
| 422 | invalid_credentials | No | Platform credentials are malformed or were rejected. |
| 422 | operation_not_supported | No | The platform’s API can’t do this. |
| 422 | reply_not_supported | No | The platform is read only: Prisma can’t reply there. |
| 422 | reply_too_long | No | The reply is over the platform’s limit. |
| 429 | rate_limited | Yes | Too many requests this minute for this key. |
| 500 | internal_error | Yes | Something failed on Prisma’s side. |
| 501 | platform_not_available | Yes | The platform can’t be connected with live keys yet. |
Error reference
missing_api_key · 401
Type: authentication_error. The request has no Authorization header, uses a scheme other than Bearer, or the value isn’t shaped like a Prisma key (pk_live_… or pk_test_…).
What to do: send Authorization: Bearer $PRISMA_API_KEY. Check that the environment variable is set and that no quotes or spaces ended up in it. See Authentication.
invalid_api_key · 401
Type: authentication_error. The key is well formed but doesn’t exist or was revoked.
What to do: use a current key. Keys can’t be recovered, only replaced: email hello@prismareviews.com for a new one.
plan_upgrade_required · 403
Type: permission_error. You tried to connect a platform that isn’t included in your plan. Yelp, Tripadvisor, Booking.com, Yotpo, REVIEWS.io and G2 start at Beam. The error includes platform.
What to do: upgrade (see Pricing) or connect a platform included in Spark: Google Business Profile, App Store, Google Play, Judge.me or Trustpilot.
resource_not_found · 404
Type: not_found_error. No review, location, connection or webhook endpoint with that ID exists in your workspace, in the mode of your key. A test key can’t see live objects and a live key can’t see test ones.
What to do: check the ID and that you use a key of the right mode. Get current IDs from the list endpoints.
reply_not_found · 404
Type: not_found_error. DELETE /v1/reviews/{id}/reply was called on a review that has no reply.
What to do: nothing to delete. If you track replies locally, refresh the review with GET /v1/reviews/{id}.
route_not_found · 404
Type: not_found_error. The method and path combination doesn’t exist, for example GET /v1/review or PUT /v1/reviews/{id}/reply.
What to do: check the path and method against the API reference. Every path starts with /v1.
connection_reauth_required · 409
Type: conflict_error. You tried to reply to a review whose location belongs to a connection that isn’t active: it is reauth_required (the platform rejected the stored token or key), pending or disconnected. The error includes connection_id.
What to do: don’t retry as is. Delete the connection and create a new one, then reply again on the new location’s review. You also get a connection.updated webhook when a connection becomes reauth_required. See Connections.
idempotency_conflict · 409
Type: conflict_error. The Idempotency-Key you sent was already used in your workspace for a different request (another body or another review).
What to do: use a new key for every distinct reply. Reuse a key only to retry exactly the same request.
invalid_request · 422
Type: invalid_request_error. A query parameter or body field is missing or invalid, or the body isn’t valid JSON. The message names the field, for example limit: Number must be less than or equal to 100.
What to do: fix the request. Retrying it unchanged gives the same error.
invalid_credentials · 422
Type: invalid_request_error. On POST /v1/connections, the credentials don’t have the fields the platform needs, or the platform rejected them when Prisma tried them. Nothing was stored.
What to do: read the message, which names the field or quotes the platform’s answer, and check the fields on Platforms. For Google Play, check that Prisma’s service account is invited for every package.
operation_not_supported · 422
Type: invalid_request_error. The platform’s API can’t do what you asked. Today this is deleting a reply on Google Play or Judge.me.
What to do: on Google Play, replace the reply with POST instead. On Judge.me, change it in Judge.me itself.
reply_not_supported · 422
Type: invalid_request_error. You sent POST or DELETE /v1/reviews/{id}/reply for a review on a read-only platform: Yelp, Tripadvisor, Booking.com, Yotpo, REVIEWS.io or G2. These platforms have no reply API for third parties. The error includes platform and url, the link to answer the review on the platform (for some platforms, the listing or product page).
What to do: answer the review on the platform with the link in url. Don’t retry: nothing was stored or sent. To skip these reviews in your reply flow, check platform before you reply.
reply_too_long · 422
Type: invalid_request_error. The reply is longer than the platform accepts: Google Business Profile 4,096 bytes, App Store 5,970 characters, Google Play 350 characters. The error includes platform and max_length.
What to do: shorten the text and send it again. Nothing was queued.
rate_limited · 429
Type: rate_limit_error. Your key made more requests this minute than your plan allows (Spark 60, Beam 120, Spectrum 600, Aurora 1,200 per minute). The Retry-After header says how many seconds until the window resets.
What to do: wait Retry-After seconds and retry. Spread bulk jobs over time and use webhooks instead of polling.
internal_error · 500
Type: api_error. Something failed on Prisma’s side. It is logged with the request_id.
What to do: retry with exponential backoff. If it keeps happening, email hello@prismareviews.com with the request_id.
platform_not_available · 501
Type: api_error. The platform can’t be connected with live keys yet. Every platform on Platforms is available today, so you should not see it; it exists for platforms added in the future, which can be tried with a test key first.
What to do: use a test key to build against the platform until it is available with live keys.
Retrying safely
Retry only when retryable is true, and back off exponentially. With 429, wait Retry-After first.
async function prisma(path, init = {}) {
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch("https://api.prismareviews.com/v1" + path, {
...init,
headers: { Authorization: "Bearer " + process.env.PRISMA_API_KEY, ...init.headers },
});
if (res.ok) return res.json();
const { error } = await res.json();
if (!error.retryable) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);
const wait = Number(res.headers.get("Retry-After")) || 2 ** attempt;
await new Promise((r) => setTimeout(r, wait * 1000));
}
throw new Error("Prisma API: too many retries");
}import os
import time
import requests
def prisma(method, path, **kw):
for attempt in range(5):
r = requests.request(
method,
"https://api.prismareviews.com/v1" + path,
headers={"Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}"},
timeout=30,
**kw,
)
if r.ok:
return r.json()
error = r.json()["error"]
if not error["retryable"]:
raise RuntimeError(f"{error['code']}: {error['message']} ({error['request_id']})")
time.sleep(int(r.headers.get("Retry-After", 2 ** attempt)))
raise RuntimeError("Prisma API: too many retries")When you retry POST /v1/reviews/{id}/reply, send the same Idempotency-Key so a reply is never posted twice.
Errors from the platforms
Prisma never calls Google, Apple, Trustpilot or any other platform inside your request, so their errors don’t come back as HTTP errors from Prisma. Syncs and replies run in a background queue, and platform errors reach you like this:
| The platform answers | What Prisma does | What you see |
|---|---|---|
| 401 or 403 on the stored token or key (revoked access, deleted key, expired refresh token) | Marks the connection reauth_required and stops using it | connection.updated webhook with status and reason; replies return 409 connection_reauth_required |
| 429 or 5xx (rate limited or down) | Retries with exponential backoff, 30 seconds doubling up to one hour, up to 8 attempts for a reply | Nothing, unless every attempt fails |
| Any other refusal of a reply (for example, a review the platform won’t let you answer) | Gives up at once | reply.status: "failed", reply.error with the platform’s answer, and a reply.failed webhook |
| Rejected credentials when connecting | Stores nothing | 422 invalid_credentials on POST /v1/connections |
A few platform specifics:
- Google Business Profile: Google refresh tokens stop working when the owner revokes access, after six months without use, or when too many tokens exist for the same account and client (see Google OAuth 2.0). On Google, a 403 on a single location (for example, the account lost access to it) fails that reply instead of marking the connection. Google also limits edits per profile (see Google Business Profile API usage limits); Prisma retries those 429s for you.
- App Store: a revoked key, or a key without the Customer Support role, makes Apple answer 401 or 403, and the connection becomes
reauth_required. Status codes are in Apple’s App Store Connect API HTTP status codes. - Trustpilot: a 401 or 403 usually means the business user lost access to the profile or the account doesn’t have Trustpilot’s API module. See Trustpilot common error messages and the Trustpilot API page.
- Google Play: a 401 or 403 means Prisma’s service account is no longer invited for that app in Play Console. See the Google Play reviews API page.
FAQ
Why does my Google connection stop working after a while?
Google refresh tokens stop working if the user revokes access, if the token goes unused for six months, or if too many tokens exist for the same account and client. Prisma marks the connection reauth_required and sends a connection.updated webhook; delete it and connect again.
What should I do with a 429 error?
Wait the number of seconds in the Retry-After header and retry. The limit is per API key and per minute, set by your plan. Platform rate limits never reach you as 429: Prisma queues and retries those itself.
Why can’t I find an old Google Play review?
The Google Play API only returns reviews created or edited in the last 7 days. Prisma keeps every review it has seen since you connected, but it cannot import older ones.
Do I get charged for failed requests?
No. Billing is per connected location, not per request, and requests over the rate limit are not even counted in your usage.
See also the API reference, the Quickstart and the Changelog.
Errors handled once, for every platform.
2 locations free. One error format for every platform.