# Errors

Every error body has the same shape:

```json
{"success": false, "message": "API key has to be provided",
 "error": {"code": "api_key_missing", "message": "API key has to be provided",
           "docs_url": "https://twitterscore.io/developers/errors/"}}
```

## Transitional behaviour (read this)

Clients built on the first version of the API branch on the body, not on the status code. For that reason errors are **currently returned with HTTP 200** and `success: false`. The real HTTP statuses in the table below are enabled after a 30-day notice in the [Changelog](/developers/changelog/). Code that checks `success` first works before and after the switch.

## Codes

| `error.code` | Meaning | HTTP status after the rollout |
|---|---|---|
| `api_key_missing` | No API key in the request. | 401 |
| `api_key_invalid` | The key is unknown. | 401 |
| `api_access_deactivated` | API access of the account is off (expired or cancelled plan): renew on the dashboard. | 403 |
| `api_key_revoked` | This key was revoked; the account is still active, create a new key. | 403 |
| `invalid_params` | A required parameter is missing or malformed. | 400 |
| `account_not_found` | No tracked account matches the username / twitter_id. | 404 |
| `method_not_allowed` | Only GET is supported. | 405 |
| `rate_limited` | Per-minute rate exceeded; retry after `Retry-After` seconds. | 429 |
| `quota_exceeded` | Monthly quota exhausted; upgrade or wait for the window to reset. | 429 |
| `server_error` | Unexpected server error; retry later. | 500 |

`rate_limited` responses carry `Retry-After: 60` (the length of the per-minute window; waiting that long is always enough); `quota_exceeded` has no `Retry-After` (the 30-day window resets on its own, see [Rate limits](/developers/rate-limits/)).