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

# Limites e convenções

> Versão, autenticação, idempotência, paginação, limites de taxa, ETag e dado pessoal fora da URL.

As mesmas regras valem para toda rota da API da Niadra: a API de dados do seu espaço e a API de controle. Conhecer as regras uma vez evita reler em cada endpoint.

## Endereço

Todo espaço tem um endereço estável, com a região dele no nome:

```text theme={null}
https://<espaço>.<região>.api.niadra.com
```

A chave carrega a região e o espaço, nunca a célula que os atende, e os SDKs montam o endereço a partir dela. Quando um espaço muda de célula, o endereço continua o mesmo; durante a mudança, a célula antiga responde 421 e os SDKs tentam de novo na hora, numa conexão nova. A topologia interna nunca faz parte do contrato.

A API de controle, de tenants, projetos, fontes, chaves, pessoas, configuração e uso, fica em `https://control.api.niadra.com`.

## Versões

A versão está no caminho: `/v1`. Campo novo ou rota nova não mudam a versão, então o seu código precisa ignorar campos que não conhece (os dois SDKs ignoram). Remover um campo ou mudar o sentido dele é `/v2`, com 12 meses em que as duas versões respondem, aviso por e-mail e o cabeçalho `Deprecation` em toda resposta da versão antiga.

## Autenticação

| Quem                                                     | Como                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Agentes e sistemas                                       | `Authorization: Bearer nia_sk_<live\|test>_<região>_<espaço>_<key_id>_<segredo>`, uma chave de fonte com escopos por rota.                                                                                                                                                                                                                                                                                                                      |
| Pessoas (Console, rotas de governança e API de controle) | `Authorization: Bearer <token>`, emitido por [`POST /v1/auth/login`](/api/control/login) (e-mail, senha e um código TOTP; no primeiro acesso, o autenticador é configurado por [`POST /v1/auth/second-factor`](/api/control/second-factor)) e renovado por [`POST /v1/auth/token`](/api/control/token). O token vale 15 minutos e nomeia um espaço. As células o conferem sem consultar o controle, pelas [chaves públicas](/api/control/jwks). |

Uma chave de fonte só autentica com o segredo; o `key_id` no prefixo é público. Os escopos são `track`, `act`, `context`, `search`, `identify`, `admin` e `analytics`. Veja [Espaços e chaves](/concepts/spaces-and-keys).

As rotas de governança (identidade, privacidade, auditoria, medição, revisão, gatilhos) aceitam uma pessoa com um dos papéis da rota ou uma chave de fonte com o escopo `admin`. Os papéis do Console são `admin`, `security`, `integration`, `review`, `analysis` e `vendor`; `admin` passa em toda checagem de papel, e uma pessoa `vendor` só enxerga as fontes nomeadas no vínculo do papel dela. Os vereditos de revisão são a exceção: só uma pessoa com o papel `review` registra.

## Idempotência

As rotas que mudam identidade ou apagam dado recebem o cabeçalho `Idempotency-Key`, e nelas ele é **obrigatório**: toda escrita de identidade (criar ou retirar asserção, unir, separar, bloquear handle, criar ou encerrar vínculo, aceitar ou descartar sugestão), [`POST /v1/forget`](/api/forget) e o [corte de uma fonte na célula](/api/source-revoke). A Niadra guarda a chave por 24 horas, com um hash do corpo:

* a mesma chave com o mesmo corpo devolve a primeira resposta de novo;
* a mesma chave com outro corpo devolve 409 `conflict`.

O lote usa, no lugar do cabeçalho, a `idempotency_key` de cada item: o id da mensagem no provedor, ou um UUIDv7 criado pelo SDK. Uma chave repetida entra em `duplicates` e nunca é gravada duas vezes, mesmo quando um webhook é reenviado dias depois.

## Erros

Os erros respondem `application/problem+json` (RFC 9457), com `type`, `title`, `status`, `detail`, `code` e `request_id`. O lote responde 200 quando todos os itens entraram, e 207 com um erro por item recusado quando não. O catálogo completo está em [Erros](/errors).

## Paginação

As listas são paginadas por um cursor opaco, em ordem estável.

| Parâmetro | Descrição                                                                                                          |
| --------- | ------------------------------------------------------------------------------------------------------------------ |
| `limit`   | Itens por página: até 200 nas listas, até 100 nas linhas do tempo, até 50 na busca de perfis e na fila de revisão. |
| `cursor`  | O `next_cursor` da página anterior.                                                                                |

`next_cursor` vem `null` na última página. Nunca monte um cursor na mão: o conteúdo dele pode mudar sem aviso.

## Limites de taxa

Passou do limite, a resposta é 429 `rate_limited` com `Retry-After` em segundos. Os limites valem por chave, e as escritas (`/v1/batch`, `/v1/ingest`, `/v1/otel`, `/v1/media`, `/v1/feedback`) são contadas à parte das leituras, então uma enxurrada de escritas nunca corta a leitura primeiro. Um 503 `unavailable` também traz `Retry-After`.

## Cache e ETag

Toda leitura determinística tem ETag: o contexto, a navegação do histórico e os objetos de negócio. O mesmo pedido, com o mesmo estado, devolve os mesmos bytes.

| Rota                             | Como perguntar "mudou?"                                                                    |
| -------------------------------- | ------------------------------------------------------------------------------------------ |
| `POST /v1/context`               | `known_etag` no corpo. Sem mudança, a resposta é 200 com `not_modified: true` e sem texto. |
| `GET /v1/context?profile_id=...` | Cabeçalho `If-None-Match`. Sem mudança, a resposta é 304.                                  |

Os SDKs mandam o ETag que têm em toda atualização do contexto.

## Dado pessoal fica fora da URL

Telefone, e-mail, documento, handle, consulta de busca e qualquer texto livre vão só no corpo da requisição, nunca no caminho nem na query. A URL acaba em log de balanceador, de firewall e em span de rastreio, fora da cifra e fora do alcance do `forget`. É por isso que `context`, `search` e `timeline` por handle são `POST`, e que a [busca de perfis](/api/profiles-search) recebe a consulta no corpo. As formas `GET` do contexto e da linha do tempo recebem um id de perfil. Um teste no nosso CI, com um valor canário, garante que nada disso aparece em URL, log, span ou mensagem de erro.

Ids que não são dado pessoal, como id de perfil, id de item, `conversation_id` ou id de objeto, podem ir no caminho.

## Rastreio

Mande um cabeçalho `traceparent` do W3C, e a Niadra o devolve na resposta. Mande `X-Request-Id` para escolher o id da requisição, ou deixe a Niadra gerar um; toda resposta traz esse id no cabeçalho `X-Request-Id` e no `request_id` de um erro. Informe o id quando falar com o suporte.

## Tamanhos

| O quê                             | Limite                                                                                                                                                                               |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Itens por lote                    | 500                                                                                                                                                                                  |
| Corpo do lote                     | 2,5 MB                                                                                                                                                                               |
| Um evento                         | 1 MB                                                                                                                                                                                 |
| Texto ou transcrição de um evento | 200.000 caracteres                                                                                                                                                                   |
| Handles por evento                | 16                                                                                                                                                                                   |
| Sujeitos por evento               | 8                                                                                                                                                                                    |
| Objetos por evento                | 16                                                                                                                                                                                   |
| Aliases de conversa               | 8                                                                                                                                                                                    |
| Handles num `identify`            | de 2 a 16                                                                                                                                                                            |
| Arquivo de mídia                  | 500 MB, enviado a uma URL pré-assinada de [`POST /v1/media/uploads`](/api/media-uploads), exatamente com os `upload_headers` que ela devolve. Mídia nunca viaja dentro de um evento. |
| Importação de arquivo             | 512 MB, `text/csv` ou `application/x-ndjson`, cada registro com até 1 MB e o cabeçalho do CSV com até 64 KB. Veja [`POST /v1/ingest/files`](/api/ingest-files).                      |
| `query` da busca e do contexto    | 2.000 caracteres                                                                                                                                                                     |
| Resposta da busca (`max_tokens`)  | de 50 a 4.000 tokens; 800 por padrão, 300 recomendado para voz                                                                                                                       |

Um lote com corpo acima de 2,5 MB, ou com mais de 500 itens, responde 422 `invalid_input`. Um item acima de 1 MB é recusado sozinho, com o erro de item `too_large`, e o resto do lote entra.

## Velocidade

| Operação                                              | Meta, na região         |
| ----------------------------------------------------- | ----------------------- |
| `context()`                                           | em menos de 100 ms      |
| Navegação do histórico (`search`, `timeline`, `open`) | em menos de 200 ms      |
| Confirmação da ingestão                               | em menos de 80 ms       |
| Mensagem, ação ou evento de sistema novo no `live`    | em menos de 1 segundo   |
| Ação ou evento de sistema dentro do contexto          | em menos de 10 segundos |
| Memória derivada de uma conversa encerrada            | em menos de 60 segundos |

Nenhum LLM roda no caminho do `context()` nem da navegação.

## Tetos iniciais de um espaço

| Recurso                                       | Teto inicial                                                     |
| --------------------------------------------- | ---------------------------------------------------------------- |
| Views de tarefa                               | 8 por espaço                                                     |
| Variantes de contexto por perfil              | 32; sai a menos lida                                             |
| Vínculos ativos por pessoa                    | 10                                                               |
| Contatos detalhados na view `account`         | 20, mais a contagem dos demais                                   |
| Padrões ativos por perfil                     | 20                                                               |
| Regras próprias de padrão                     | 25; janela de até 365 dias e nunca além da retenção da evidência |
| Regras de gatilho                             | 50 por espaço; 100 disparos por minuto                           |
| Fila de mortos dos webhooks                   | 7 dias                                                           |
| Exportação contínua                           | 1 agendamento por destino; intervalo mínimo de 1 hora            |
| Revisão por amostra                           | 500 amostras por dia; guardadas por 12 meses                     |
| Assistente de configuração                    | 20 execuções por mês; 200 amostras por execução                  |
| Disparos de gatilho e execuções de exportação | guardados por 13 meses                                           |
| Eventos de tipo não mapeado                   | 7 dias em armazenamento frio, para remapear                      |

São valores de partida, definidos no seu contrato. Fale com a gente quando um caso de uso pedir mais.

## Nomes no contrato

Todo nome na API, nos SDKs, nas ferramentas MCP, nos eventos e nos webhooks é em inglês, em ASCII. Os campos são `snake_case` (`conversation_id`, `occurred_at`); horários são ISO 8601 com fuso; os enums usam valores fixos em minúsculas, como `message`, `system_event` e `action` para `kind`, ou `customer`, `ai_agent`, `human_agent` e `system` para `speaker`. Os níveis de verificação são `V0` a `V4` e `no_customer`. Dentro da `/v1`, nenhum valor muda de sentido.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Erros" href="/errors">
    cada código e o que fazer com ele.
  </Card>

  <Card title="Eventos e o lote" href="/concepts/events">
    idempotência e erro por item na prática.
  </Card>

  <Card title="Espaços e chaves" href="/concepts/spaces-and-keys">
    escopos, fontes e o formato da chave.
  </Card>

  <Card title="A API da Niadra" href="/api">
    todas as rotas, geradas do OpenAPI.
  </Card>
</CardGroup>
