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

# Erros e códigos HTTP

> Envelope de erro da API v1, status comuns e boas práticas

Rotas sob `/v1/*` retornam erros em JSON padronizado.

## Envelope de erro (API pública)

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "error": {
    "code": "validation_error",
    "message": "The request body is invalid.",
    "request_id": "req_7f3a2b1c"
  }
}
```

| Campo           | Descrição                                             |
| --------------- | ----------------------------------------------------- |
| `error.code`    | Código estável para lógica do integrador              |
| `error.message` | Texto legível (inglês) — não trate como API estável   |
| `request_id`    | Identificador para suporte — também em `X-Request-Id` |

## Status HTTP frequentes

| Status | Situação típica                                                  |
| ------ | ---------------------------------------------------------------- |
| `401`  | Chave ausente, revogada ou inválida                              |
| `403`  | Chave sem escopo na rota; projeto inativo                        |
| `404`  | Job ou `media_id` não encontrado / expirado                      |
| `422`  | URL inválida, plataforma não suportada ou formato indisponível   |
| `429`  | Rate limit, cota diária ou concorrência de jobs                  |
| `500`  | Erro interno (retente com backoff; abra ticket com `request_id`) |

## Códigos de domínio

| Código                       | HTTP | Significado                                        |
| ---------------------------- | ---- | -------------------------------------------------- |
| `invalid_api_key`            | 401  | Chave ausente ou hash inválido                     |
| `revoked_api_key`            | 401  | Chave revogada no dashboard                        |
| `forbidden`                  | 403  | Escopo insuficiente ou projeto inativo             |
| `validation_error`           | 422  | Body JSON inválido                                 |
| `invalid_url`                | 422  | URL malformada ou não HTTP(S)                      |
| `unsupported_platform`       | 422  | Host não suportado (inclui YouTube)                |
| `unsupported_format`         | 422  | `format` não existe no resolve                     |
| `media_not_found`            | 404  | `media_id` inexistente ou expirado (TTL padrão 1h) |
| `media_unavailable`          | 422  | Mídia indisponível no origin                       |
| `job_not_found`              | 404  | Job inexistente ou de outro projeto                |
| `rate_limit_exceeded`        | 429  | Limite por minuto (60 req/min por chave)           |
| `daily_limit_exceeded`       | 429  | Limite diário do projeto (1.000 req/dia)           |
| `concurrency_limit_exceeded` | 429  | Jobs simultâneos excedidos (máx. 2)                |
| `internal_error`             | 500  | Falha não recuperável no servidor                  |

## Erros em jobs `failed`

Quando um job falha, `GET /jobs/{jobId}` retorna `status: "failed"` com:

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "data": {
    "status": "failed",
    "error": {
      "code": "media_unavailable",
      "message": "media_unavailable"
    }
  }
}
```

O `error.message` em jobs falhos pode repetir o código — prefira `error.code` para lógica.

## Validação de body

Campos inválidos retornam `422` com `validation_error`. Exemplos:

* `url` ausente em `POST /media/resolve`
* `url` e `media_id` ausentes em `POST /media/download`
* `format` ausente no download
* `url` com mais de 2048 caracteres

## Rate limiting global (IP)

Além dos limites por API key, a infraestrutura aplica limites por IP antes do router `/v1`:

* 100 req/min por IP
* 30 req/5s por IP (burst)

Esses retornam um formato diferente (`error.api.rate_limited`) sem `request_id`. Em integrações normais server-to-server, o limite por chave é o relevante.

## Boas práticas

* Registre sempre `request_id` nos logs do seu servidor ao tratar erros `5xx`
* Não interprete `message` como API estável — prefira `error.code`
* Em polling de jobs, trate `404` como job expirado ou inexistente
* `unsupported_platform` e `invalid_url` não devem ser retentados

Veja também: [Tratamento de erros na prática](/pages/guides/tratamento-erros-pratica) · [Rate limiting](/api-reference/rate-limiting)
