> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clipstake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> The error envelope, the codes to branch on, and how to retry.

Every failure returns the same JSON envelope with an HTTP status that matches.

```json theme={null}
{
  "error": {
    "code": "quota_exceeded",
    "message": "This workspace has reached its submission limit. Upgrade on the Billing page to keep adding.",
    "request_id": "req_01K5A7P8VM2T6R4W9C3H"
  }
}
```

<Warning>
  Branch on `code`, never on `message`. The code is the contract. The message
  is prose and can be reworded at any time.
</Warning>

Log `request_id`. Quoting it lets support find the exact request.

## Codes

| Status | `code`                  | What happened                                                                                                                                                                                                             |
| ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `invalid_request`       | The body, a parameter, or a cursor is not valid.                                                                                                                                                                          |
| 401    | `unauthorized`          | The API key is missing, malformed, or revoked.                                                                                                                                                                            |
| 402    | `quota_exceeded`        | The workspace is at its submission or account limit.                                                                                                                                                                      |
| 402    | `payment_required`      | A renewal failed and the grace period has ended.                                                                                                                                                                          |
| 403    | `analytics_not_enabled` | Analytics is off for this workspace.                                                                                                                                                                                      |
| 403    | `forbidden`             | Reserved. Workspace keys have no scopes today, so the API does not return it yet.                                                                                                                                         |
| 404    | `not_found`             | No such resource is reachable with this key.                                                                                                                                                                              |
| 409    | `conflict`              | The resource is in a state this operation cannot apply to. For example, pausing or resuming `unavailable` media, resuming `parked` media before the account is reconnected, or using a connection that needs a reconnect. |
| 429    | `rate_limited`          | Instagram is rate limiting the connected account. Wait and retry.                                                                                                                                                         |
| 500    | `internal_error`        | Our fault. Retry, and quote the `request_id` if it persists.                                                                                                                                                              |

## 404 hides what you cannot reach

Anything outside your workspace answers `404`, not `403`. A `403` would confirm
that the id exists, which turns every endpoint that takes an id into a way to
test whether another workspace's resources are real.

So `404` means "no such resource, for you". It does not distinguish a wrong id
from someone else's id, and it cannot.

## Retrying

| Situation                             | What to do                                                                                                                                                                   |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `429 rate_limited`                    | Wait, then retry. Use `Retry-After` when it is present.                                                                                                                      |
| `409 conflict` on `POST /submissions` | A lookup for that account is already running. Retry once after `Retry-After`. If there is no `Retry-After`, the account's authorization was rejected: reconnect the account. |
| `409 conflict` on a resume            | Do not retry. Fix the cause first, such as reconnecting the account.                                                                                                         |
| `5xx`                                 | Retry with backoff. Submitting is idempotent per project and shortcode.                                                                                                      |
| `402`                                 | Do not retry. The answer stays the same until the plan changes or the invoice is paid.                                                                                       |

`Retry-After` is sent in seconds when the response carries a delay.

<Note>
  Do not retry a `402` in a loop. Waiting does not create quota. Raise the plan
  on the Billing page, or wait for the next paid period.
</Note>

## Content type

Send `Content-Type: application/json` on every mutation. A POST without it is
refused with `415` before any ClipStake code runs, so it never reaches the
envelope above.

## Reaching a path that is not an endpoint

`api.clipstake.com` serves the API under `/v1`. Any other path returns the same
`404 not_found` envelope, so a mistyped path is still something your client can
parse. Opening one in a browser shows a readable page instead.
