# Errors

One error shape for every endpoint, with what to do next.

Every error has the same shape and an HTTP status that matches it.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "scheduledAt: must be in the future",
    "action": "edit_post"
  },
  "requestId": "req_..."
}
```

- `code`: stable, safe to branch on.
- `message`: for people. It names the fields at fault.
- `action`: what to do next: `reconnect_account`, `edit_post`, `retry` or `contact_support`.
- `network`: the network's own `code`, `subcode` and `message`, when a network refused.
- `requestId`: also in the `Request-Id` header. Send it to support.

## Codes [#codes]

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `invalid_request` | A field is missing or wrong |
| 401 | `unauthorized` | No key, or the key is not valid |
| 403 | `forbidden` | The key cannot reach this profile or action |
| 404 | `not_found` | No such object, or not in your team |
| 409 | `conflict` | The request conflicts with the object's current state |
| 422 | `capability_missing` | The account cannot do this: see its `capabilities` |
| 429 | `rate_limited` | Too many requests: wait for `Retry-After` seconds |
| 500 | `internal` | Our side failed. Retry, and send the `requestId` if it keeps failing |

## Retries [#retries]

Send an `Idempotency-Key` header on every `POST`. A retry with the same key gets the same answer for 24 hours, so a post is never created twice.
