Errors
The status codes and error bodies the App Developer API returns, and how to handle each one.
Check the HTTP status code first. The error body depends on which host you called, and some errors are plain text even when the Content-Type header says JSON, so parse defensively.
Status codes
| Code | Meaning | Common causes |
|---|---|---|
200 | Success | Storefront endpoints also return 200 with no data for a product ID Yotpo doesn't know. See Storefront errors. |
400 | The request is invalid | A missing or malformed parameter or body field. Wrong client credentials or a missing field when you request a token. |
401 | Not authenticated | No access token, a token sent as Authorization: Bearer, or a token that's wrong, revoked or expired. |
403 | Forbidden | An app-level webhook path called with the numeric app ID instead of your app's client ID. See Forbidden. |
404 | Not found | A path or HTTP method the API doesn't serve. An unknown store ID on a storefront endpoint. An unknown resource ID (the endpoint's reference page shows the body). |
429 | Too many requests | You went over the rate limit for that endpoint and store. See Rate limits. |
Each endpoint's reference page lists the other errors it returns, with example bodies.
Authentication errors (401)
401)Every endpoint on developers.yotpo.com that needs a token returns one of these:
| Cause | Body |
|---|---|
No token, or the token sent only as Authorization: Bearer | {"error": "invalid_request", "error_description": "The access token is missing"} |
A token that's wrong, revoked or expired, or a store token from another Yotpo API (such as api.yotpo.com) | {"error": "invalid_token", "error_description": "The access token is invalid or has expired"} |
invalid_request means the API didn't find a token at all: send it in the X-Yotpo-Token header. invalid_token means it found one but can't use it. Tokens don't expire on their own, so this usually means the merchant uninstalled your app. See How to handle each error.
Forbidden (403)
403)The app-level webhook endpoints (/core/v3/applications/{application_id}/...) take your app's client ID as application_id: the 32-character Application ID you got when you registered your app. With the numeric app ID they return:
{ "message": "Forbidden" }Rate limits (429)
429)Over the rate limit for an endpoint, you get 429 with a Retry-After header that says how many seconds to wait:
{
"message": "API rate limit exceeded",
"request_id": "41c1544aa131c145725e5862fea4c031"
}The limits and the RateLimit-* headers on every response are in Guidelines and Conventions.
Paths the API doesn't serve (404)
404)A path or method that developers.yotpo.com doesn't serve returns:
{
"message": "no Route matched with those values",
"request_id": "5b943f4c94d45a495bc5fe7094092e60"
}This includes a real path called with the wrong method, for example DELETE on a path that only supports GET: you get 404, not 405. Check the method and path against the reference page. Log request_id and include it when you contact Yotpo.
Token endpoint errors (POST /v2/oauth2/token)
POST /v2/oauth2/token)| Cause | Status | Body |
|---|---|---|
Wrong client_id or client_secret | 400 | 400 BAD_REQUEST "{"error":"invalid_client","error_description":"Invalid client authentication"}" |
A required field is missing, for example redirect_uri or client_id | 400 | Plain text, for example No value for field: "No value for field: "redirect_uri" provided." provided. |
These bodies aren't valid JSON, even though Content-Type is application/json. Read the status code, then search the body for the error name (invalid_client) or the missing field. Send client_id and client_secret in the request body: an Authorization: Basic header isn't read.
Storefront errors
Storefront endpoints (api-cdn.yotpo.com and storefront.yotpo.com/loyalty) need no token, so they don't return 401.
| Cause | Status | Body |
|---|---|---|
Unknown store ID (api-cdn.yotpo.com) | 404 | Plain text: Account not found |
A required query parameter is missing, for example page or perPage on Retrieve bottomline scores | 400 | {"type": "about:blank", "title": "Bad Request", "status": 400, "detail": "Required parameter 'perPage' is not present.", "instance": "..."} (application/problem+json) |
reviewType missing on Retrieve top reviews | 400 | Plain text: Invalid Request |
A required body field is missing on Product Potential Points, for example product_id | 400 | {"error": "Missing body parameter 'product_potential_points.product_id'."} |
Storefront endpoints don't return 404 for a product ID Yotpo doesn't know. They return 200 with no reviews:
{
"pagination": { "page": 0, "perPage": 5, "total": 0 },
"bottomline": { "totalReview": 0, "averageScore": 0.0 },
"products": [],
"reviews": []
}To tell "no reviews yet" apart from "wrong product ID", check that you're sending the product ID the merchant's eCommerce platform sends to Yotpo.
How to handle each error
400 Bad Request
Fix the request before you retry: sending it again unchanged returns the same error. Check the endpoint's reference page for required parameters and body fields.
401 Unauthorized
invalid_request: send the token in theX-Yotpo-Tokenheader.Authorization: Bearerisn't read.invalid_token: check that you're using the token for this store, since each store the merchant installed your app on has its own token. If the token was working before, the merchant has probably uninstalled your app. After 3401responses in a row for a store that used to work, mark the integration as disconnected in your product and let the merchant reinstall it (see Authenticating with OAuth 2.0).
Don't retry a 401 in a loop: it won't succeed until the token changes.
403 Forbidden
Check that application_id in the path is your app's client ID, not the numeric app ID.
404 Not Found
no Route matched with those values: check the HTTP method and the path, including the base URL. Endpoints on other hosts (api-cdn.yotpo.com,storefront.yotpo.com/loyalty,api.yotpo.com) say so on their reference pages.- Any other
404: the resource ID or store ID doesn't exist. Don't retry.
429 Too Many Requests
Wait the number of seconds in Retry-After, then retry. If you hit 429 often, spread your requests out and watch RateLimit-Remaining.
Updated about 3 hours ago
What’s Next
How to test your app without affecting real shoppers
