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

# Erros

> Um formato de erro, um code estável, e o que fazer com cada tipo.

Toda resposta que não é 2xx tem o mesmo body:

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_failed",
    "message": "email is not a valid address.",
    "param": "email",
    "detail": [
      { "field": "email", "message": "value is not a valid email address", "code": "value_error" }
    ],
    "request_id": "req_8f2c...",
    "documentation_url": "https://docs.chatsailer.com/guides/errors"
  }
}
```

Desvie por `type` para o fluxo de controle e por `code` para o tratamento
específico. Os dois são estáveis; `message` é escrito para humanos e pode ser
reescrito.

Sempre logue `request_id`. Ele é ecoado no header de resposta `X-Request-ID`,
e citá-lo nos deixa encontrar a sua requisição exata.

## Tipos

| Type                    | HTTP     | O que significa                                                 | O que fazer                                                                                  |
| ----------------------- | -------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `invalid_request_error` | 400, 422 | A requisição está malformada ou falha a validação               | Corrija a requisição. Leia `detail` para os campos ofensores. Não tente de novo sem mudanças |
| `authentication_error`  | 401      | Token ausente, malformado, revogado ou expirado                 | Cheque o header `Authorization`. Não tente de novo sem mudanças                              |
| `permission_error`      | 403      | Autenticado, mas não permitido                                  | Costuma ser um scope faltando, ou uma política de write do workspace. Veja abaixo            |
| `not_found_error`       | 404      | Não existe esse registro, **ou** ele está fora do seu workspace | Não tente de novo                                                                            |
| `conflict_error`        | 409      | Conflita com o estado existente, p. ex. um duplicado            | Reconcilie, depois tente de novo                                                             |
| `rate_limit_error`      | 429      | Pedidos demais                                                  | Faça backoff e tente de novo — veja abaixo                                                   |
| `api_error`             | 5xx      | Algo quebrou do nosso lado                                      | Tente de novo com backoff. Se persistir, mande o `request_id`                                |

<Note>
  Um 404 não distingue "não existe" de "pertence a outro workspace". É
  deliberado: distinguir os dois deixaria qualquer um sondar ids de registro
  entre workspaces.
</Note>

## Scopes faltando

Um 403 de um cheque de scope nomeia exatamente o que falta, para você não ter
que adivinhar:

```json theme={null}
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This endpoint requires the contacts:write scope."
  }
}
```

Um 403 que *não* é `insufficient_scope` costuma significar política de write
do workspace — por exemplo, uma entidade espelhada de um CRM externo. Chame
`GET /v1/capabilities` para ver quais entidades você pode escrever.

## Tentando de novo

Tente de novo `rate_limit_error` e `api_error`. Não tente de novo erros 4xx
sem mudanças; eles vão falhar igual.

```python theme={null}
for attempt in range(5):
    response = httpx.request(method, url, headers=headers, json=body)
    if response.status_code < 400:
        return response.json()
    if response.status_code not in (429, 500, 502, 503, 504):
        raise SailerError(response.json()["error"])
    time.sleep(2 ** attempt)
```

Use backoff exponencial com jitter. Tentar de novo imediatamente durante um
rate limit o estende.
