# Error codes and how to fix them

> Every Data API error code with its HTTP status, what causes it, how to fix it and whether to retry. Errors never cost credits.

*Source: https://shopsavvy.com/data/documentation/errors* · Part of the [ShopSavvy Data API documentation](https://shopsavvy.com/data/documentation.md)

---

Every error response has the same shape. `error` is kept as a plain string for older clients; read `error_detail` in new code.

```json
{
  "success": false,
  "error": "A product identifier is required.",
  "error_detail": {
    "code": "ERR_IDENTIFIER_REQUIRED",
    "message": "An 'ids' parameter is required. It must contain one or more product identifiers (barcode, UPC, EAN, ISBN, GTIN, ASIN, model number, URL, or ShopSavvy product ID), separated by commas.",
    "action": "Pass identifiers in the ids query parameter, e.g. ?ids=611247373064 (any type: barcode, ASIN, URL, model number). Parameters named barcode, upc or asin are not read.",
    "docs_url": "https://shopsavvy.com/data/documentation/errors#err_identifier_required"
  },
  "meta": {
    "request_id": "4f9d2c1e-…",
    "credits_used": 0,
    "credits_remaining": 0,
    "rate_limit_remaining": 958
  }
}
```

- Branch on `error_detail.code`, not on the HTTP status (two different codes share 429) or the message (messages get more specific over time).
- `action` is a one-line fix you can show to a developer. `docs_url` links to the entry for that code below.
- **Errors never cost credits.** `meta.credits_used` is always `0`; if any credits had been recorded for the request they are reversed, so your balance matches.
- Quote `meta.request_id` when you contact support@shopsavvy.com.

| Code | HTTP | Meaning | Retry? |
|------|------|---------|--------|
| `ERR_AUTH_MISSING` | 401 | No API key was sent. | No, fix the request |
| `ERR_AUTH_INVALID` | 401 | The key is not in the `ss_live_` format. | No |
| `ERR_AUTH_REVOKED` | 401 | The key does not exist or was revoked. | No |
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | The account has no Data API plan. | No |
| `ERR_SUBSCRIPTION_INACTIVE` | 403 | The plan is canceled or unpaid past the grace window. | No |
| `ERR_CREDITS_EXHAUSTED` | 429 | This month's credits (and any bonus credits) are used up. | Not until the period resets or you upgrade |
| `ERR_RATE_LIMIT` | 429 | More than 1,000 requests in the rolling hour. | Yes, after `Retry-After` seconds |
| `ERR_INVALID_PARAMS` | 400 | A parameter is missing, malformed or over a limit. | No, fix the request |
| `ERR_IDENTIFIER_REQUIRED` | 400 | No identifiers were sent in `ids` (or `id` on reviews). | No, fix the request |
| `ERR_PRODUCT_NOT_FOUND` | 404 | None of the identifiers matched a product. | No; try another identifier |
| `ERR_ENDPOINT_NOT_FOUND` | 404 | The batch job or webhook id does not exist. | No |
| `ERR_METHOD_NOT_ALLOWED` | 405 | The endpoint is not available to this caller (for example, in the playground sandbox). | No |
| `ERR_INTERNAL` | 500 | Something failed on our side. | Yes, with backoff |

## ERR_AUTH_MISSING

**HTTP 401.** The request had no `Authorization` header and no `api_key` query parameter. Send `Authorization: Bearer ss_live_…` with every request. See [Overview & Authentication](https://shopsavvy.com/data/documentation/authentication).

## ERR_AUTH_INVALID

**HTTP 401.** The value is not a ShopSavvy key: keys are `ss_live_` followed by 32 characters. Check for a missing `Bearer ` prefix, extra quotes or whitespace from an environment file, or a truncated copy. Copy the key again from [API Keys](https://shopsavvy.com/data/api-keys).

## ERR_AUTH_REVOKED

**HTTP 401.** The key has the right format but no active key matches it, usually because it was revoked or belongs to a deleted account. Create a new key at [API Keys](https://shopsavvy.com/data/api-keys).

## ERR_SUBSCRIPTION_REQUIRED

**HTTP 403.** The key is valid but the account has no Data API plan. Start a plan (Starter has a 14-day trial) at [shopsavvy.com/data](https://shopsavvy.com/data#pricing).

## ERR_SUBSCRIPTION_INACTIVE

**HTTP 403.** The plan exists but is canceled, or a payment failed and the one-week grace window has passed. Update the payment method in [Billing](https://shopsavvy.com/data/billing).

## ERR_CREDITS_EXHAUSTED

**HTTP 429**, without a `Retry-After` header. The plan's monthly credits, and any referral bonus credits, are used up. Retrying will not help until the billing period resets; upgrade in [Billing](https://shopsavvy.com/data/billing) to continue now. `GET /v1/usage` (0 credits) shows your balance and period dates. Credits are explained in [Pricing & Credits](https://shopsavvy.com/data/documentation/pricing-credits).

## ERR_RATE_LIMIT

**HTTP 429**, with a `Retry-After` header in seconds. The account made more than 1,000 requests in the last rolling hour, counted across all its keys. Wait `Retry-After` seconds, then retry; rejected requests do not count against the limit. Pack up to 100 identifiers into one request to use fewer requests. See [Rate Limits](https://shopsavvy.com/data/documentation/rate-limits).

## ERR_INVALID_PARAMS

**HTTP 400.** A parameter is malformed or over a limit. The `message` names the parameter. Common causes:

- More than 100 identifiers in `ids` (or in `identifiers` on `POST /products/batch`). Split the request.
- A price-history window longer than 366 days, or a `start`/`end` that is not `YYYY-MM-DD`.
- A `schedule` other than `hourly`, `daily` or `weekly`.
- A webhook without a `url` or `events`, an unknown event type, or more than 5 webhooks on the account.

No credits are charged.

## ERR_IDENTIFIER_REQUIRED

**HTTP 400.** No identifiers were found. Identifiers go in the `ids` query parameter, comma-separated, whatever their type: `?ids=611247373064,B07GV2S1GS`. Parameters named `barcode=`, `upc=`, `asin=` or `url=` are not read. `GET /products/reviews` takes a single `id`. URL-encode product URLs and names.

## ERR_PRODUCT_NOT_FOUND

**HTTP 404.** None of the identifiers matched a product. The `message` says what was tried: a barcode whose check digit fails (usually a missing or extra digit), a barcode that is not in the catalog yet, or other identifiers to try (ASIN, model number, product URL). When some identifiers match and some don't, you get a 200 with the matches only; use each product's `match.identifier` to see which ones came back. Not-found costs nothing.

## ERR_ENDPOINT_NOT_FOUND

**HTTP 404.** The batch job (`GET /batch/{batchId}`) or webhook (`/webhooks/{id}`) does not exist or belongs to another account. Batch ids come from the `batch.id` of an asynchronous `POST /products/batch`; webhook ids from `GET /webhooks`.

## ERR_METHOD_NOT_ALLOWED

**HTTP 405.** The endpoint exists but is not available to this caller. The playground's Live Sandbox only serves the sample products and endpoints it lists; use your own key for everything else.

## ERR_INTERNAL

**HTTP 500.** An unexpected failure on our side. Any credits recorded for the request are reversed. Retry with exponential backoff; if it keeps happening, email support@shopsavvy.com with the `request_id`.
