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

# Fundamentos

> Convenções de paginação, filtros, IDs, cache, rate limit e erros da API.

## Paginação por cursor

As listagens usam paginação por cursor e retornam `data` e `has_more`.
O limite padrão é 25 itens e pode variar de 1 a 100.

```json theme={null}
{
  "data": [
    {
      "object": "segment",
      "id": "seg_ckxyz123",
      "name": "Clientes VIP"
    }
  ],
  "has_more": true
}
```

Para buscar a página seguinte, envie o `id` do último item como
`starting_after`:

```bash theme={null}
curl --get https://api.bevits.com/v1/segments \
  --header "Authorization: Bearer $BEVITS_API_KEY" \
  --data-urlencode "limit=25" \
  --data-urlencode "starting_after=seg_ckxyz123"
```

Continue enquanto `has_more` for `true`. Não reutilize o cursor de um tipo de
recurso em outra listagem.

## IDs públicos

IDs são opacos e carregam um prefixo que identifica o recurso.

| Prefixo | Recurso            |
| ------- | ------------------ |
| `org_`  | Organização        |
| `bak_`  | API key            |
| `cus_`  | Cliente            |
| `seg_`  | Segmento           |
| `pur_`  | Compra             |
| `tag_`  | Tag                |
| `atr_`  | Atributo           |
| `flw_`  | Flow               |
| `emc_`  | Campanha de e-mail |

Trate IDs como strings. Não remova o prefixo nem tente inferir seu conteúdo.

## Filtros e datas

Filtros são enviados como parâmetros de query. Datas usam ISO 8601 com offset;
as respostas são normalizadas para UTC.

```bash theme={null}
curl --get https://api.bevits.com/v1/customers \
  --header "Authorization: Bearer $BEVITS_API_KEY" \
  --data-urlencode "is_subscribed=true" \
  --data-urlencode "updated_since=2026-07-01T00:00:00Z"
```

Campos sem valor são omitidos das respostas, em vez de retornarem `null`.
Valores monetários usam centavos, como `total_spent_in_cents: 15990`.

## Erros

Erros nunca são retornados com status `200`. O campo `error.type` é estável
para automação; `message` é legível por humanos; `request_id` identifica a
requisição para suporte.

```json theme={null}
{
  "error": {
    "type": "validation_error",
    "message": "Invalid input: expected number, received NaN",
    "param": "limit",
    "request_id": "req_07f6cdc3c20249d6afcd90b4"
  }
}
```

| HTTP  | `error.type`           | Significado                                          |
| ----- | ---------------------- | ---------------------------------------------------- |
| `400` | `invalid_request`      | Rota, cursor ou formato da requisição inválido.      |
| `401` | `authentication_error` | API key ausente, inválida, expirada ou revogada.     |
| `403` | `permission_denied`    | A credencial não possui a permissão necessária.      |
| `404` | `not_found`            | O recurso não existe ou não pertence à organização.  |
| `409` | `conflict`             | A requisição conflita com o estado atual do recurso. |
| `422` | `validation_error`     | Um parâmetro ou valor não passou pela validação.     |
| `429` | `rate_limited`         | O limite de requisições foi excedido.                |
| `500` | `internal_error`       | Erro inesperado no servidor.                         |

## Rate limit

O limite inicial é de **600 requisições por minuto, por API key**. As respostas
autenticadas incluem:

```http theme={null}
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 2026-07-25T21:31:00.000Z
```

Ao receber `429`, aguarde o número de segundos indicado em `Retry-After` antes
de tentar novamente. Use backoff com jitter em integrações automatizadas.

## Cache condicional

Respostas de recursos incluem `ETag`. Envie esse valor em `If-None-Match` para
evitar transferir novamente um conteúdo que não mudou:

```http theme={null}
If-None-Match: "v1-4ad31f5efb6b8f35"
```

Quando o conteúdo for idêntico, a API responde `304 Not Modified` sem corpo.
