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

# Convenções da API

> Padrões que valem para todos os endpoints: erros, IDs, dinheiro, listagem e rate limits

Estas convenções valem para toda a API — o comportamento descrito aqui não é repetido endpoint a endpoint.

## Base URL e versionamento

```text theme={null}
https://api.iuzypay.com/v1
```

Todas as rotas de negócio vivem sob `/v1`. Mudanças incompatíveis entrarão em uma versão nova de caminho; dentro do `/v1`, campos novos podem ser **adicionados** a qualquer momento — escreva seu cliente para ignorar campos desconhecidos.

## Requisições e respostas

* Corpo em JSON (UTF-8), com header `Content-Type: application/json`.
* Corpos de requisição são limitados a **1 MB**.

## Erros

Todo erro vem no mesmo envelope, com um `code` estável (feito para máquinas) e uma `message` descritiva (feita para humanos — não faça parsing dela):

```json theme={null}
{
  "error": {
    "code": "invalid_request",
    "message": "name is required"
  }
}
```

| Status | `code` típico          | Quando acontece                                                  |
| ------ | ---------------------- | ---------------------------------------------------------------- |
| `400`  | `invalid_request`      | Corpo malformado ou campo inválido                               |
| `401`  | `unauthorized`         | API key ausente, malformada ou revogada                          |
| `403`  | `forbidden`            | Autenticado, mas sem permissão para a ação                       |
| `404`  | `not_found`            | Recurso inexistente ou de outra organização                      |
| `409`  | específico do conflito | Estado atual impede a ação (ex.: `duplicate_bump`, `last_owner`) |
| `429`  | `rate_limited`         | Limite de requisições excedido — aguarde e tente de novo         |
| `500`  | `internal_error`       | Falha inesperada do lado da iuzypay                              |

## Identificadores

IDs de recursos são **UUIDs** (ex.: `6f1c9d2e-8a4b-4c3d-9e2f-1a2b3c4d5e6f`). Trate-os como strings opacas.

## Valores monetários

Dinheiro é sempre representado como **inteiro em centavos** acompanhado da moeda — nunca como número decimal:

```json theme={null}
{
  "price_cents": 19790,
  "currency": "BRL"
}
```

`19790` significa R\$ 197,90. Faça toda a aritmética em inteiros; converta para reais apenas na exibição.

## Datas

Timestamps são strings **RFC 3339** em UTC (ex.: `2026-07-06T14:32:00Z`).

## Listagem e paginação

Endpoints de listagem seguem o mesmo contrato:

```text theme={null}
GET /v1/<recurso>?page=1&per_page=20&q=busca
```

| Parâmetro  | Default | Comportamento                                                                           |
| ---------- | ------- | --------------------------------------------------------------------------------------- |
| `page`     | `1`     | Valores fora do intervalo são **ajustados**, nunca rejeitados (`page=0` vira `1`)       |
| `per_page` | `20`    | Limitado ao intervalo 1–100; fora dele volta ao default                                 |
| `q`        | —       | Busca textual, sem case; caracteres especiais (`%`, `_`, `\`) são tratados literalmente |

Filtros específicos (ex.: `status`) são documentados em cada recurso; um valor desconhecido equivale a não filtrar.

A resposta traz a lista sob o nome do recurso, mais o bloco de paginação:

```json theme={null}
{
  "products": [ ... ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 137
  }
}
```

## Rate limiting

Rotas públicas (sem autenticação) têm limites por IP. Ao exceder, a API responde `429` com `code: "rate_limited"` — implemente retry com espera exponencial.
