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

# Erros

> Formato padronizado de erros e códigos de status.

A API Repass usa códigos de status HTTP convencionais e um **envelope de erro único** em qualquer endpoint de qualquer módulo (programas, afiliados, conversões, comissões, payouts, etc.). Falhas de negócio são erros de domínio tipados, lançados pelos casos de uso e mapeados para HTTP num único ponto, então você integra contra um contrato estável, sem precisar conhecer a estrutura interna da plataforma.

## Envelope de erro

Toda resposta de erro tem o mesmo formato: um objeto raiz `error` com `type`, `code` e `message`. Os campos `param` e `issues` são opcionais e só aparecem quando aplicáveis.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_not_found",
    "message": "Affiliate aff_01J9Z3K7Q8ABCDEF1234567890 not found"
  }
}
```

<ResponseField name="error" type="object">
  <Expandable title="propriedades" defaultOpen>
    <ResponseField name="type" type="string" required>
      Categoria do erro. Um de `invalid_request_error`, `authentication_error`, `permission_error`, `idempotency_error` ou `api_error`. Útil para roteamento genérico de tratamento (ex.: tudo `authentication_error` dispara re-login).
    </ResponseField>

    <ResponseField name="code" type="string" required>
      Código estável e legível por máquina (ex.: `resource_not_found`, `parameter_invalid`, `idempotency_in_flight`). Prefira o `code` ao `message` para lógica de tratamento.
    </ResponseField>

    <ResponseField name="message" type="string" required>
      Mensagem legível por humanos descrevendo o que deu errado. Destinada a logs e debugging: não faça parsing nem mostre diretamente ao usuário final.
    </ResponseField>

    <ResponseField name="param" type="string">
      Presente quando o erro aponta para um parâmetro específico do request. Em erros de validação, é o caminho do campo com pontos (ex.: `tiers.0.minCount`).
    </ResponseField>

    <ResponseField name="issues" type="array">
      Presente apenas em erros de validação de schema (Zod). Lista os problemas detalhados de validação, um item por campo inválido.
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  Campos ausentes simplesmente não aparecem no JSON. Trate `param` e `issues` como opcionais.
</Note>

## Status HTTP por categoria

Cada `type` corresponde a uma faixa de status HTTP. Use o status para a decisão de alto nível (sucesso vs. erro do cliente vs. erro do servidor) e o `code` para o tratamento específico.

| `type`                  | Status HTTP         | Significado                                                                                                                                  |
| ----------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_request_error` | `400`, `404`, `409` | O request é inválido: parâmetro ruim, recurso inexistente ou conflito de estado. Em geral, corrigível pelo cliente.                          |
| `authentication_error`  | `401`               | Credenciais ausentes, inválidas ou expiradas. Veja [Autenticação](/docs/autenticacao).                                                            |
| `permission_error`      | `403`               | Autenticado, mas sem permissão para a operação (ex.: papel insuficiente).                                                                    |
| `idempotency_error`     | `400`, `409`        | Problema com a `Idempotency-Key`: reuso com payload diferente, ou request ainda em andamento. Veja [Idempotência](/docs/convencoes/idempotencia). |
| `api_error`             | `500`               | Erro inesperado do lado do servidor. Não é culpa do request; pode ser repetido.                                                              |

<Warning>
  O status HTTP `200` a `299` indica sucesso. `400` a `499` indica um problema com o request (não repita sem corrigir, exceto `409 idempotency_in_flight`). `500` indica falha do servidor (seguro repetir com backoff).
</Warning>

## Catálogo de códigos

Mapeamento completo de cada situação para status, `type` e `code`. Este mapeamento é aplicado globalmente em todos os endpoints.

| Situação                                               | Status | `type`                  | `code`                   |
| ------------------------------------------------------ | ------ | ----------------------- | ------------------------ |
| Recurso não encontrado                                 | `404`  | `invalid_request_error` | `resource_not_found`     |
| Não autenticado / credencial inválida                  | `401`  | `authentication_error`  | `unauthorized`           |
| Sem permissão para a operação                          | `403`  | `permission_error`      | `not_allowed`            |
| Conflito de estado do recurso                          | `409`  | `invalid_request_error` | `conflict`               |
| Entrada inválida (regra de negócio)                    | `400`  | `invalid_request_error` | `parameter_invalid`      |
| Validação de schema (Zod)                              | `400`  | `invalid_request_error` | `parameter_invalid`      |
| `Idempotency-Key` reutilizada com payload diferente    | `400`  | `idempotency_error`     | `idempotency_key_reused` |
| Request com mesma `Idempotency-Key` ainda em andamento | `409`  | `idempotency_error`     | `idempotency_in_flight`  |
| Erro de domínio sem mapeamento explícito               | `400`  | `invalid_request_error` | código da própria classe |
| Erro inesperado do servidor                            | `500`  | `api_error`             | `internal_error`         |

<Note>
  Erros `4xx` originados por validações de transporte (ex.: `413` por arquivo grande demais num upload multipart) também seguem o envelope padrão, com o status original e `type: invalid_request_error`.
</Note>

## Erros de validação (Zod)

Quando o corpo, a query ou os parâmetros de path falham na validação de schema, a API retorna `400` com `code: parameter_invalid`. A resposta inclui:

* `param`: o caminho do **primeiro** campo inválido, derivado do `instancePath` com barras convertidas em pontos (ex.: `/tiers/0/minCount` vira `tiers.0.minCount`).
* `issues`: o array completo de problemas de validação, um item por campo, para que você localize **todos** os erros de uma vez.

Exemplo: criando uma regra de comissão `percentage` com o `percentage` fora do intervalo permitido (`0` a `100`).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.userepass.com/programs/prog_01J9Z3K7Q8ABCDEF1234567890/commission-rules \
    -H "Authorization: Bearer rstr_..." \
    -H "Content-Type: application/json" \
    -d '{
      "type": "percentage",
      "percentage": 250
    }'
  ```

  ```json Resposta 400 theme={null}
  {
    "error": {
      "type": "invalid_request_error",
      "code": "parameter_invalid",
      "message": "Number must be less than or equal to 100",
      "param": "percentage",
      "issues": [
        {
          "instancePath": "/percentage",
          "schemaPath": "#/properties/percentage/maximum",
          "keyword": "maximum",
          "params": { "limit": 100 },
          "message": "Number must be less than or equal to 100"
        }
      ]
    }
  }
  ```
</CodeGroup>

<Tip>
  Valores monetários são inteiros em **centavos** (ex.: `fixedAmountCents: 1990` = R\$ 19,90), nunca floats. Percentuais de **entrada** usam a forma decimal `0` a `100` (ex.: `percentage: 15` = 15%); a plataforma armazena e devolve percentuais em **basis points** (`10000` bps = 100%). Enviar um decimal onde se espera centavos resulta em `parameter_invalid`. Veja [IDs e recursos](/docs/convencoes/ids-e-recursos).
</Tip>

## Exemplos por categoria

<AccordionGroup>
  <Accordion title="404: Recurso não encontrado">
    Um ID válido que não corresponde a nenhum recurso da sua organização (ou de outra organização, já que o multi-tenancy é estrito) retorna `404`.

    ```json theme={null}
    {
      "error": {
        "type": "invalid_request_error",
        "code": "resource_not_found",
        "message": "Affiliate aff_01J9Z3K7Q8ABCDEF1234567890 not found"
      }
    }
    ```
  </Accordion>

  <Accordion title="401: Não autenticado">
    Request sem token, com token inválido/expirado ou sem o header `Authorization`.

    ```bash theme={null}
    curl -X GET https://api.userepass.com/affiliates
    # sem header Authorization
    ```

    ```json theme={null}
    {
      "error": {
        "type": "authentication_error",
        "code": "unauthorized",
        "message": "Unauthorized"
      }
    }
    ```

    Veja [Autenticação](/docs/autenticacao) para obter e usar uma API key (`rstr_...`).
  </Accordion>

  <Accordion title="403: Sem permissão">
    Você está autenticado, mas seu papel na organização não permite a operação (ex.: criar um job de reprocessamento exige papel `owner` ou `admin`).

    ```json theme={null}
    {
      "error": {
        "type": "permission_error",
        "code": "not_allowed",
        "message": "Insufficient role for this operation"
      }
    }
    ```
  </Accordion>

  <Accordion title="409: Conflito de estado">
    A operação conflita com o estado atual do recurso (ex.: aprovar uma conversão que já foi paga, ou criar um recurso com um identificador único já em uso).

    ```json theme={null}
    {
      "error": {
        "type": "invalid_request_error",
        "code": "conflict",
        "message": "Conversion conv_01J9Z3K7Q8ABCDEF1234567890 is already paid"
      }
    }
    ```
  </Accordion>

  <Accordion title="400 / 409: Idempotência">
    Reusar uma `Idempotency-Key` com um corpo diferente do request original retorna `400 idempotency_key_reused`. Repetir um request enquanto o original ainda está em processamento retorna `409 idempotency_in_flight`.

    ```json theme={null}
    {
      "error": {
        "type": "idempotency_error",
        "code": "idempotency_key_reused",
        "message": "Idempotency-Key was reused with a different request"
      }
    }
    ```

    ```json theme={null}
    {
      "error": {
        "type": "idempotency_error",
        "code": "idempotency_in_flight",
        "message": "A request with this Idempotency-Key is still in progress"
      }
    }
    ```

    Veja [Idempotência](/docs/convencoes/idempotencia) para o ciclo completo (escopo `org:user`, TTL de 24h, replay).
  </Accordion>

  <Accordion title="500: Erro do servidor">
    Um erro inesperado do lado do servidor. O request pode estar correto; é seguro repetir com backoff exponencial. Se persistir, contate o suporte com o horário e o endpoint.

    ```json theme={null}
    {
      "error": {
        "type": "api_error",
        "code": "internal_error",
        "message": "Internal server error"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Como tratar erros

Trate erros com base no status HTTP primeiro e no `code` em seguida. O `type` serve para classificação genérica; o `code` para decisões específicas.

```mermaid theme={null}
flowchart TD
    R[Resposta da API] --> S{Status HTTP}
    S -->|2xx| OK[Sucesso]
    S -->|401| AUTH[authentication_error<br/>renovar credenciais]
    S -->|403| PERM[permission_error<br/>verificar papel do ator]
    S -->|404| NF[resource_not_found<br/>verificar o ID]
    S -->|400/409| C{code}
    C -->|parameter_invalid| FIX[corrigir payload<br/>usar param + issues]
    C -->|conflict| ST[reavaliar estado do recurso]
    C -->|idempotency_in_flight| RETRY[aguardar e repetir]
    C -->|idempotency_key_reused| KEY[usar nova Idempotency-Key]
    S -->|500| SRV[api_error<br/>repetir com backoff]
```

<Steps>
  <Step title="Cheque o status HTTP">
    `2xx` é sucesso. `4xx` é um problema com o request: não repita sem mudar algo (exceto `409 idempotency_in_flight`). `5xx` é o servidor: repita com backoff exponencial.
  </Step>

  <Step title="Use error.code para a lógica">
    Faça branch no `code` (estável), nunca na `message` (sujeita a mudança). Para validação, use `param` e `issues` para apontar o(s) campo(s) ao usuário ou ao log.
  </Step>

  <Step title="Não repita erros determinísticos">
    Um `400`/`404`/`403` se repetirá com o mesmo resultado. Em fluxos com `Idempotency-Key`, um `4xx` determinístico é gravado e retornado como replay nas próximas tentativas com a mesma chave.
  </Step>
</Steps>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Autenticação" icon="key" href="/docs/autenticacao">
    Como autenticar com API keys `rstr_...` e evitar `401`.
  </Card>

  <Card title="Idempotência" icon="rotate" href="/docs/convencoes/idempotencia">
    Escopo, TTL e replay dos erros `idempotency_error`.
  </Card>

  <Card title="IDs e recursos" icon="fingerprint" href="/docs/convencoes/ids-e-recursos">
    Formato dos IDs, centavos e basis points para evitar `parameter_invalid`.
  </Card>

  <Card title="Paginação" icon="list" href="/docs/convencoes/paginacao">
    Limites e cursores das listagens, e seus erros de validação.
  </Card>
</CardGroup>
