# Erros

> Formato do erro, o que cada status HTTP pede de você e o catálogo completo de códigos.

Todo erro, em toda rota e em todo status, tem o mesmo corpo:

```json
{ "code": "INSUFFICIENT_CREDITS", "extra": { "credits_needed": 121, "current_balance": 40 } }
```

| Campo | Tipo | Descrição |
|---|---|---|
| `code` | string | Identificador estável, em maiúsculas, de um conjunto fechado. Faça `switch` nele. |
| `extra` | object | Só aparece quando há algo para agir: o que faltou, qual campo falhou, quais ids foram recusados. |

Não existe mensagem em texto. O servidor não sabe o idioma do seu usuário, e texto não se trata em `switch`: traduza o `code` na sua interface.

## Status HTTP

| Status | Significa | O que fazer |
|---|---|---|
| `400` | O corpo da requisição está errado | Corrija. Repetir igual dá o mesmo erro. |
| `401` | Chave ausente, revogada ou vencida | Confira o header `X-Api-Key`. |
| `402` | Créditos insuficientes | Leia `extra.credits_needed` e recarregue. |
| `403` | A fonte ou a conta está fora de alcance | Não há o que repetir. |
| `404` | Não existe neste workspace | Confira o id e o workspace. |
| `409` | Existe, mas o estado atual recusa a operação | Espere e tente de novo. |
| `410` | Existiu e expirou | Envie de novo ou renderize de novo. |
| `422` | Link válido, vídeo inutilizável | Use outra fonte. |
| `429` | Limite de requisições | Espere os segundos de `Retry-After`. |
| `5xx` | Falha nossa | Repita com espera crescente. |

## Validação

Corpo ou query fora do schema responde `VALIDATION_ERROR`, e `extra.errors` lista os campos que falharam, com ponto entre os níveis:

```json title="400 Bad Request"
{ "code": "VALIDATION_ERROR", "extra": { "errors": ["video_id", "timeframe.end"] } }
```

## Rota inexistente

Um caminho que não existe responde `404 NOT_FOUND`, com `extra.openapi` apontando para a especificação e `extra.docs` para o `llms.txt` desta documentação. É assim que um agente que chutou a rota encontra o caminho certo.

## Tratando erros

**Node.js**

```js
const response = await fetch(`${API}/clips`, { method: "POST", headers, body });
if (!response.ok) {
	const { code, extra } = await response.json();
	switch (code) {
		case "INSUFFICIENT_CREDITS":
			return askForTopUp(extra.credits_needed);
		case "RATE_LIMIT_EXCEEDED":
		case "SERVICE_UNAVAILABLE":
			return retryAfter(Number(response.headers.get("Retry-After")));
		default:
			throw new Error(code);
	}
}
```

**Python**

```python
response = requests.post(f"{API}/clips", headers=HEADERS, json=body)
if not response.ok:
    error = response.json()
    match error["code"]:
        case "INSUFFICIENT_CREDITS":
            return ask_for_top_up(error["extra"]["credits_needed"])
        case "RATE_LIMIT_EXCEEDED" | "SERVICE_UNAVAILABLE":
            return retry_after(int(response.headers["Retry-After"]))
        case _:
            raise RuntimeError(error["code"])
```

## Erro de job

Um job que falha depois de aceito não devolve status HTTP de erro: a rota de leitura responde `200` com `status: "failed"` e o motivo em `error_code`. Na clipagem, por exemplo, `DOWNLOAD_PRIVATE_VIDEO` diz que o vídeo ficou privado depois da análise. Veja [Clipagem](/clipping#quando-falha).

## Catálogo de códigos

Todos os códigos que a API devolve, gerados da especificação a cada publicação desta documentação. Para o significado de um código numa rota, abra a rota na [referência](/reference).

| Code | Status | Devolvido por |
|---|---|---|
| `CONNECTION_INVALID` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `DELETE_FAILED` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `DELETE_LIMIT_REACHED` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `DELETE_NOT_SUPPORTED` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `FILE_TOO_LARGE` | 400 | `POST /videos/upload`, `POST /transcriptions/upload`, `POST /personas/sources/upload` |
| `IMAGES_INVALID` | 400 | `POST /generations` |
| `INVALID_CHANNEL_URL` | 400 | `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `INVALID_CONNECTIONS` | 400 | `POST /posts`, `PATCH /posts/{id}` |
| `INVALID_DURATION_RANGE` | 400 | `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `INVALID_FILE_TYPE` | 400 | `POST /videos/upload`, `POST /transcriptions/upload`, `POST /personas/sources/upload` |
| `INVALID_IMAGE` | 400 | `POST /personas/faces`, `POST /personas/{id}/shots/photos`, `POST /generations/images` |
| `INVALID_METADATA` | 400 | `POST /posts` |
| `INVALID_OBSERVING_TYPE` | 400 | `GET /monitors/{id}/broadcasts`, `GET /monitors/{id}/broadcasts/{broadcastId}/clips`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/apply_template`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render` |
| `INVALID_SCHEDULED_AT` | 400 | `POST /posts`, `PATCH /posts/{id}` |
| `INVALID_STRATEGY_OPTIONS` | 400 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `INVALID_TRANSLATE_LANGUAGE` | 400 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `ITEM_NOT_EDITABLE` | 400 | `PATCH /posts/{id}` |
| `ITEM_NOT_FAILED` | 400 | `POST /posts/{id}/items/{itemId}/retry` |
| `ITEM_NOT_REMOVABLE` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `ITEMS_EMPTY` | 400 | `PATCH /posts/{id}` |
| `MEDIA_METADATA_REQUIRED` | 400 | `POST /transcriptions` |
| `MEDIA_TOO_LONG` | 400 | `POST /transcriptions` |
| `MISSING_WORKSPACE_ID` | 400 | qualquer rota |
| `MODE_UNSUPPORTED` | 400 | `POST /generations` |
| `MODEL_UNAVAILABLE` | 400 | `POST /generations`, `POST /generations/improve` |
| `NO_PENDING_ITEMS` | 400 | `POST /posts/{id}/publish` |
| `NO_RENDERS_SELECTED` | 400 | `POST /renders/bulk-download` |
| `NOTHING_TO_UPDATE` | 400 | `PATCH /posts/{id}` |
| `PERMISSION_MISSING` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `PLATFORM_UNAVAILABLE` | 400 | `POST /posts` |
| `PRODUCT_URL_INVALID` | 400 | `POST /personas/{id}/shots/product` |
| `PUBLISHED_ID_MISSING` | 400 | `DELETE /posts/{id}/items/{itemId}` |
| `RATIO_INVALID` | 400 | `POST /generations` |
| `RESOLUTION_INVALID` | 400 | `POST /generations` |
| `SCENE_ACTION_UNSUPPORTED` | 400 | `POST /personas/{id}/shots` |
| `SCHEDULE_LOCKED` | 400 | `PATCH /posts/{id}` |
| `SECONDS_INVALID` | 400 | `POST /generations` |
| `STYLE_REQUIRED` | 400 | `GET /personas/swap/quote`, `POST /personas/{id}/videos` |
| `STYLE_UNSUPPORTED` | 400 | `GET /personas/swap/quote`, `POST /personas/{id}/videos` |
| `TARGET_UNSUPPORTED` | 400 | `POST /personas/{id}/videos` |
| `TIMEFRAME_OUT_OF_BOUNDS` | 400 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `TIMEFRAME_TOO_SHORT` | 400 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `TOO_MANY_RENDERS` | 400 | `POST /renders/bulk-download` |
| `VALIDATION_ERROR` | 400 | qualquer rota |
| `VIDEO_DURATION_OUT_OF_RANGE` | 400 | `GET /personas/swap/quote`, `POST /personas/{id}/videos` |
| `VIDEO_TOO_LONG` | 400 | `POST /videos/upload/complete`, `POST /clips`, `POST /clips/info`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `VIDEO_TOO_SHORT` | 400 | `POST /videos/upload/complete` |
| `VIDEO_UNSUPPORTED` | 400 | `GET /personas/swap/quote`, `POST /personas/{id}/videos` |
| `VOICE_INVALID` | 400 | `POST /generations` |
| `WORKSPACE_NOT_AUTHORIZED` | 400 | qualquer rota |
| `UNAUTHORIZED` | 401 | qualquer rota |
| `CREDIT_CHARGE_FAILED` | 402 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `INSUFFICIENT_CREDITS` | 402 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry`, `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop`, `POST /transcriptions`, `POST /personas`, `POST /personas/{id}/regenerate`, `POST /personas/{id}/videos`, `POST /personas/{id}/shots`, `POST /generations`, `POST /generations/improve` |
| `ACCESS_DENIED` | 403 | `POST /clips/info` |
| `ACCOUNT_BLOCKED` | 403 | qualquer rota |
| `AGE_RESTRICTED` | 403 | `POST /clips/info` |
| `CLIP_FORBIDDEN` | 403 | `DELETE /clips/{videoId}` |
| `CLIP_RESULT_FORBIDDEN` | 403 | `DELETE /clips/{videoId}/submissions/{submissionId}/clips/{clipId}` |
| `COPYRIGHT_BLOCKED` | 403 | `POST /clips/info` |
| `DAILY_LIMIT_EXCEEDED` | 403 | `POST /posts` |
| `FORBIDDEN` | 403 | qualquer rota |
| `LIVE_CLIPS_NOT_AVAILABLE` | 403 | `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `PLATFORM_NOT_SUPPORTED` | 403 | `POST /clips`, `POST /clips/info`, `POST /clips/{videoId}/submissions/{submissionId}/retry`, `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `POST_FORBIDDEN` | 403 | `DELETE /posts/{id}/items/{itemId}` |
| `PRIVATE_VIDEO` | 403 | `POST /clips/info` |
| `REGION_BLOCKED` | 403 | `POST /clips/info` |
| `RENDER_FORBIDDEN` | 403 | `DELETE /renders/{renderId}` |
| `SUBMISSION_FORBIDDEN` | 403 | `DELETE /clips/{videoId}/submissions/{submissionId}` |
| `WORKSPACE_FORBIDDEN` | 403 | qualquer rota |
| `CLIP_NOT_FOUND` | 404 | `DELETE /clips/{videoId}`, `GET /clips/{videoId}/submissions`, `DELETE /clips/{videoId}/submissions/{submissionId}`, `DELETE /clips/{videoId}/submissions/{submissionId}/clips/{clipId}`, `GET /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/subtitles`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render` |
| `CLIP_RESULT_NOT_FOUND` | 404 | `DELETE /clips/{videoId}/submissions/{submissionId}/clips/{clipId}`, `GET /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/subtitles`, `POST /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/render` |
| `CONNECTION_NOT_FOUND` | 404, 400 | `GET /connections/{id}`, `DELETE /posts/{id}/items/{itemId}` |
| `CREATOR_NOT_FOUND` | 404 | `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `EDIT_NOT_FOUND` | 404 | `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render`, `POST /renders` |
| `EDITS_NOT_FOUND` | 404 | `POST /posts`, `PATCH /posts/{id}` |
| `FACE_NOT_FOUND` | 404 | `POST /personas` |
| `FILE_NOT_FOUND` | 404 | `POST /videos/upload/multipart/complete`, `POST /videos/upload/multipart/abort`, `POST /videos/upload/complete`, `POST /personas/sources/upload/complete` |
| `GENERATION_NOT_FOUND` | 404 | `GET /generations/{id}`, `DELETE /generations/{id}`, `POST /generations/{id}/edit`, `POST /generations/{id}/feedback`, `POST /generations/{id}/refund`, `GET /generations/{id}/download` |
| `IMAGE_NOT_FOUND` | 404 | `POST /generations` |
| `ITEM_NOT_FOUND` | 404 | `POST /posts/{id}/items/{itemId}/retry`, `DELETE /posts/{id}/items/{itemId}` |
| `JOB_NOT_FOUND` | 404 | `GET /renders/bulk-download/{jobId}` |
| `MEDIA_NOT_FOUND` | 404 | `POST /transcriptions`, `GET /personas/swap/quote`, `POST /personas/{id}/videos` |
| `METADATA_UNAVAILABLE` | 404 | `POST /clips/info` |
| `MONITORING_NOT_FOUND` | 404 | `POST /monitors`, `GET /monitors/{id}`, `PATCH /monitors/{id}`, `DELETE /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop`, `GET /monitors/{id}/broadcasts`, `GET /monitors/{id}/broadcasts/{broadcastId}/clips`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/apply_template`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render` |
| `NO_SUBTITLES` | 404 | `GET /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/subtitles` |
| `NO_VALID_RENDERS` | 404 | `POST /renders/bulk-download` |
| `NO_VIDEO_INFO` | 404 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `NOT_FOUND` | 404 | qualquer rota |
| `PERSONA_NOT_FOUND` | 404 | `POST /personas/presets/{presetId}`, `POST /personas`, `GET /personas/{id}`, `DELETE /personas/{id}`, `POST /personas/{id}/regenerate`, `POST /personas/{id}/versions/{versionId}/restore`, `POST /personas/{id}/versions/{versionId}/feedback`, `POST /personas/{id}/save`, `POST /personas/{id}/videos`, `POST /personas/{id}/shots/product`, `POST /personas/{id}/shots` |
| `PHOTO_NOT_FOUND` | 404 | `POST /personas/{id}/shots` |
| `POST_NOT_FOUND` | 404 | `GET /posts/{id}`, `PATCH /posts/{id}`, `POST /posts/{id}/publish`, `POST /posts/{id}/items/{itemId}/retry`, `DELETE /posts/{id}/items/{itemId}` |
| `PRESET_NOT_FOUND` | 404 | `POST /personas/presets/{presetId}`, `PUT /personas/presets/{presetId}/favorite` |
| `RENDER_NOT_FOUND` | 404 | `GET /renders/{renderId}`, `DELETE /renders/{renderId}`, `GET /renders/{renderId}/download` |
| `SHOT_NOT_FOUND` | 404 | `GET /personas/{id}/shots/{shotId}` |
| `STRATEGY_NOT_FOUND` | 404 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry`, `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop` |
| `STREAM_NOT_FOUND` | 404 | `GET /monitors/{id}/broadcasts/{broadcastId}/clips` |
| `SUBMISSION_NOT_FOUND` | 404 | `GET /clips/{videoId}/submissions/{submissionId}`, `DELETE /clips/{videoId}/submissions/{submissionId}`, `POST /clips/{videoId}/submissions/{submissionId}/retry`, `POST /clips/{videoId}/submissions/{submissionId}/apply_template`, `GET /clips/{videoId}/submissions/{submissionId}/clips`, `DELETE /clips/{videoId}/submissions/{submissionId}/clips/{clipId}`, `GET /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/subtitles` |
| `TEMPLATE_NOT_FOUND` | 404 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry`, `POST /clips/{videoId}/submissions/{submissionId}/apply_template`, `POST /monitors`, `PATCH /monitors/{id}`, `POST /monitors/{id}/start`, `POST /monitors/{id}/stop`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/apply_template` |
| `TRANSCRIPTION_NOT_FOUND` | 404 | `GET /transcriptions/{transcriptionId}`, `DELETE /transcriptions/{transcriptionId}`, `GET /transcriptions/{transcriptionId}/transcript`, `GET /transcriptions/{transcriptionId}/download` |
| `UNAVAILABLE` | 404 | `POST /clips/info` |
| `VERSION_NOT_FOUND` | 404 | `POST /personas/{id}/versions/{versionId}/restore`, `POST /personas/{id}/versions/{versionId}/feedback`, `POST /personas/{id}/videos`, `POST /personas/{id}/shots` |
| `VIDEO_ID_NOT_FOUND` | 404 | `POST /clips/info` |
| `VIDEO_NOT_FOUND` | 404 | `GET /clips/{videoId}/submissions/{submissionId}`, `POST /personas/{id}/videos/{videoId}/feedback`, `GET /personas/{id}/videos/{videoId}` |
| `WORKSPACE_NOT_FOUND` | 404 | `GET /workspace` |
| `STORAGE_LIMIT_EXCEEDED` | 406 | `POST /transcriptions/upload`, `POST /personas/sources/upload`, `POST /generations/images` |
| `CARD_LOCKED` | 409 | `POST /personas/{id}/regenerate`, `POST /personas/{id}/versions/{versionId}/restore` |
| `CARD_NOT_READY` | 409 | `POST /personas/{id}/save` |
| `DUPLICATE_POST` | 409 | `POST /posts` |
| `MEDIA_REFUNDED` | 409 | `POST /posts`, `PATCH /posts/{id}` |
| `PRICE_CHANGED` | 409 | `POST /personas/{id}/videos`, `POST /personas/{id}/shots`, `POST /generations` |
| `REFUND_AFTER_DOWNLOAD` | 409 | `POST /generations/{id}/refund` |
| `REFUND_AFTER_POST` | 409 | `POST /generations/{id}/refund` |
| `REFUND_ALREADY_REQUESTED` | 409 | `POST /generations/{id}/refund` |
| `REFUND_NOT_ALLOWED` | 409 | `POST /generations/{id}/refund` |
| `RENDER_ALREADY_IN_PROGRESS` | 409 | `POST /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/render`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render`, `POST /renders` |
| `SUBMISSION_NOT_FAILED` | 409 | `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `TRANSCRIPTION_NOT_READY` | 409 | `GET /transcriptions/{transcriptionId}/transcript`, `GET /transcriptions/{transcriptionId}/download` |
| `VIDEO_ALREADY_PROCESSING` | 409 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `VIDEO_IN_PROGRESS` | 409 | `POST /personas/{id}/videos` |
| `JOB_EXPIRED` | 410 | `GET /renders/bulk-download/{jobId}` |
| `RECORDING_EXPIRED` | 410 | `GET /monitors/{id}/broadcasts/{broadcastId}/clips`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render`, `POST /posts` |
| `RENDER_FILE_EXPIRED` | 410 | `GET /renders/{renderId}/download` |
| `SUBMISSION_EXPIRED` | 410 | `GET /clips/{videoId}/submissions/{submissionId}`, `GET /clips/{videoId}/submissions/{submissionId}/clips` |
| `AUDIO_ONLY` | 422 | `POST /clips/info` |
| `CHANNEL_URL` | 422 | `POST /clips/info` |
| `INVALID_DIMENSIONS` | 422 | `POST /clips/info` |
| `INVALID_DURATION` | 422 | `POST /clips/info` |
| `INVALID_URL` | 422 | `POST /clips/info` |
| `LIVE_STREAM` | 422 | `POST /clips/info` |
| `MEDIA_UNREADABLE` | 422 | `POST /transcriptions`, `POST /personas/sources/upload/complete` |
| `PLAYLIST_URL` | 422 | `POST /clips/info` |
| `PREMIUM_ONLY` | 422 | `POST /clips/info` |
| `PRODUCT_NOT_READABLE` | 422 | `POST /personas/{id}/shots/product` |
| `SHORTS_NOT_SUPPORTED` | 422 | `POST /clips/info` |
| `BATCH_ALREADY_RUNNING` | 429 | `POST /clips/{videoId}/submissions/{submissionId}/apply_template`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/apply_template` |
| `PRODUCT_RATE_LIMITED` | 429 | `POST /personas/{id}/shots/product` |
| `RATE_LIMIT_EXCEEDED` | 429 | `POST /clips/info`, `POST /monitors` |
| `TOO_MANY_PENDING_CLIPS` | 429 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `TOO_MANY_RUNNING` | 429 | `POST /generations` |
| `CANCEL_FAILED` | 500 | `DELETE /renders/{renderId}` |
| `CREDIT_CHARGE_ERROR` | 500 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `FAILED_TO_GET_VIDEO` | 500 | `POST /clips/info` |
| `INTERNAL_ERROR` | 500 | `POST /videos/upload/complete`, `POST /personas/sources/upload/complete` |
| `INTERNAL_SERVER_ERROR` | 500 | qualquer rota |
| `PRESIGN_FAILED` | 500 | `POST /videos/upload`, `POST /transcriptions/upload`, `POST /personas/sources/upload` |
| `PROCESSING_ERROR` | 500 | `POST /clips`, `POST /clips/{videoId}/submissions/{submissionId}/retry` |
| `RENDER_FAILED` | 500 | `POST /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/render`, `POST /monitors/{id}/broadcasts/{broadcastId}/clips/{clipId}/render`, `POST /renders` |
| `RENDER_SETUP_FAILED` | 500 | `POST /clips/{videoId}/submissions/{submissionId}/clips/{clipId}/render` |
| `SIGNED_URL_FAILED` | 500 | `GET /renders/{renderId}/download` |
| `UNKNOWN_ERROR` | 500 | `POST /clips/info`, `POST /posts` |
| `AI_UNAVAILABLE` | 502 | `POST /generations/improve` |
| `MEDIA_UNAVAILABLE` | 502 | `GET /personas/catalog`, `POST /personas/presets/{presetId}`, `GET /personas/swap/quote`, `POST /personas/{id}/videos`, `POST /personas/{id}/shots`, `POST /generations` |
| `SERVICE_UNAVAILABLE` | 503 | `POST /clips/info` |
