# Errors (https://getuser.app/docs/errors)

> Every error code the API returns, and what to do about it.

Errors always have the same shape, with an HTTP status that fits:

```json
{
  "error": {
    "code": "not_enough_credits",
    "message": "This needs 25 credits; you have 10.",
    "docs": "https://getuser.app/docs/errors#not_enough_credits"
  }
}
```

- `code` is stable: switch on it.
- `message` is English, for people; it may change.
- `invalid_input` also has `issues[]` (field and problem); `setup_incomplete` has `detail.gate` (`videos` or `slideshows`) and `detail.missing`.

## All codes

| Code | HTTP | Example message | What to do |
| --- | --- | --- | --- |
| `invalid_input` | 400 | The request is not valid. See issues. | Read `error.issues[]`: each names the field and what is wrong with it. |
| `invalid_key` | 401 | The API key is missing, wrong or revoked. Make a new one at getuser.app/settings/api. | Send `Authorization: Bearer gu_…`. Make a new key in Settings › Connect to AI. |
| `not_enough_credits` | 402 | This needs 25 credits; you have 10. | Wait for the next credits, make fewer, or upgrade. Nothing was charged. |
| `suspended` | 403 | This account is paused. Email support@getuser.app if you think that is a mistake. | Email support@getuser.app. |
| `terms_not_accepted` | 403 | The Terms changed. Open getuser.app once and accept them, then try again. | Sign in to getuser.app in a browser and accept the new Terms, then retry. |
| `not_found` | 404 | Not found in this workspace. | Check the id. Ids from another workspace are never visible. |
| `already_queued` | 409 | This video is already queued or rendering. | Poll `GET /v1/videos/{id}` instead of queueing again. |
| `already_rendered` | 409 | This video is already done. | Read its `download_url` with `GET /v1/videos/{id}`. |
| `already_scheduled` | 409 | This video is already scheduled. | Read the posting plan with `GET /v1/plan`. |
| `idempotency_conflict` | 409 | This Idempotency-Key was used with a different request body. | Use a new key for a new request; reuse a key only to retry the same body. |
| `request_in_progress` | 409 | A request with this Idempotency-Key is still running. | Wait a few seconds, then retry with the same key: it answers the first request’s result. |
| `too_large` | 413 | The file is larger than your plan allows. | Trim or compress the file, or upgrade. |
| `setup_incomplete` | 422 | Finish setting up at getuser.app first. Videos need your app, 5 demos and your own reaction. Missing: demos. | `detail.gate` says which: videos need the app, 5 demos and the founder’s own reaction; slideshows need the app and 5 images. The founder adds what `detail.missing` lists in the app. |
| `storage_full` | 422 | Your storage is full. Delete videos you no longer need at getuser.app/videos, or upgrade. | The founder deletes old videos at getuser.app/videos (the API cannot delete), or upgrades. |
| `queue_full` | 422 | 40 videos are already waiting. Let some finish first. | Let some finish, then queue more. |
| `ai_paused` | 422 | AI writing is paused for a moment. Try again later. | Retry later. |
| `ai_unavailable` | 422 | The AI writer did not answer. No credits were charged; try again later. | Retry later. |
| `rerenders_used` | 422 | That's all the free re-renders this month. | Make a new video instead. |
| `uploads_used` | 422 | That's all the uploads your plan allows for now. | Reuse uploads you have, wait, or upgrade. |
| `posts_used` | 422 | That's all the posts your plan allows this month. | Wait for next month or upgrade. |
| `ai_hour_used` | 422 | That is a lot of AI writes this hour. Try again in a bit. | Retry in a while. |
| `ai_day_used` | 422 | That is all the AI writes for today. Try again tomorrow. | Retry tomorrow. |
| `files_gone` | 422 | The files of this video are gone. Render it again first. | Render it again first. |
| `not_failed` | 422 | Only a failed post can be tried again. | Check the status before retrying. |
| `account_not_connected` | 422 | That account is not connected. | The founder connects the TikTok or Instagram account in the app. |
| `text_too_long` | 422 | The text is too long for the screen. | Shorten the hook or ending text named in `detail.field`. |
| `not_ready` | 422 | An upload it uses is still processing or was deleted. | Poll `GET /v1/assets/{id}` until `status` is `ready`. |
| `no_demo` | 422 | Upload a demo of your app first. | Upload a demo (see Uploading footage). |
| `no_personas` | 422 | No persona fits these settings. | Widen `persona_ids` or leave it out. |
| `no_lines` | 422 | No hook line fits these settings. | Use `lines: 'all'`, or write lines with `POST /v1/ai/lines`. |
| `too_many_keys` | 422 | A workspace can have 10 live keys. Revoke one first. | Revoke a key you no longer use. |
| `rate_limited` | 429 | Too many requests. Wait for Retry-After seconds. | Wait for the `Retry-After` seconds, then retry. |
| `internal` | 500 | Something went wrong on our side. Try again. | Retry with the same Idempotency-Key. |
| `unavailable` | 503 | Getuser is paused for maintenance. Try again in a few minutes. | Retry in a few minutes. |

## Retrying

Retry `429`, `500` and `503`, with the same `Idempotency-Key` and a growing wait. Do not retry `4xx` business refusals unchanged: they answer the same until something changes.
