Pular para o conteúdo principal
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:
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 e por 30 dias depois dela, a célula antiga responde 421 wrong_cell a qualquer chave ou pessoa do espaço, em vez de servir o que ainda guarda, e os SDKs tentam de novo na hora, numa conexão nova, que a borda leva à célula nova. A topologia interna nunca faz parte do contrato: um espaço numa célula dedicada do plano Regulado tem o mesmo formato de endereço. A API de controle, de tenants, projetos, fontes, chaves, pessoas, configuração e uso, fica em https://control.api.niadra.com. O webhook genérico também atende em https://mtls.<região>.api.niadra.com, o endereço que pede um certificado de cliente no aperto de mão, para as fontes autenticadas por mtls; veja Webhooks de sistema.

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, em toda resposta da versão antiga, Deprecation: @<instante> (RFC 9745), que diz desde quando, e Sunset: <data HTTP> (RFC 8594), que diz quando ela para, expostos no CORS com o Link de rel="deprecation". Os dois SDKs registram um aviso, uma vez por rota, quando uma resposta traz Deprecation. Hoje nada de /v1 foi depreciado, então nenhuma resposta traz esses cabeçalhos. A política de versões da API diz o que conta como mudança incompatível e como o aviso chega.

Autenticação

O login que confirma o autenticador devolve também dez códigos de recuperação, uma vez só. Quando o aplicativo se perde, cada código entra uma vez, em recovery_code no lugar de totp, e a resposta diz quantos restam em recovery_codes_left. A Niadra guarda só um HMAC-SHA256 de cada código. A própria pessoa gera códigos novos e troca de aplicativo com a senha de novo, e um admin redefine o segundo fator de quem perdeu o aplicativo e os códigos. Pessoas novas chegam por convite, um link de uso único para escolher a senha, ou pelo SSO da empresa, por OIDC ou SAML 2.0. Uma pessoa desativada perde o plano de controle na hora; um token já emitido vale na API de dados até vencer. 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, analytics, agent_memory, agent_memory:write, replay, coordinate, state:push e agent_state; os quatro últimos valem só num espaço que ligou a funcionalidade deles. Veja Espaços e chaves. 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 e o corte de uma fonte na célula. 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. As escritas das funcionalidades de agente também o exigem: declarar, reivindicar, reservar um efeito, criar e aceitar uma transferência (coordenação); promover turnos, criar um cenário e reportar uma execução (registros de turno); criar uma retenção legal, um pedido de revisão e liberar um conteúdo. O registro de turnos e o push de estado usam, em vez do cabeçalho, o turn_id de cada registro e a versão de cada item: o mesmo turno enviado duas vezes é um turno só, e um campo só avança sob uma versão maior.

Erros

Os erros das rotas 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.

Paginação

As listas são paginadas por um cursor opaco, em ordem estável. 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. Um espaço criado há poucos segundos, ou em restauração, responde 503 unavailable com Retry-After: 5 enquanto o banco dele é preparado, por até cerca de um minuto. Os SDKs mandam de novo sozinhos os eventos da fila, que esperam guardados até dar certo; uma leitura de contexto ou do histórico não é repetida e volta vazia. Quem chama a API direto deve respeitar o Retry-After e repetir o pedido.

Cache e ETag

O contexto tem ETag. O mesmo pedido, com o mesmo estado, devolve os mesmos bytes. 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 recebe a consulta no corpo. As formas GET do contexto e da linha do tempo recebem um id de perfil. Ids que não são dado pessoal, como id de perfil, id de item ou id de objeto, podem ir no caminho. Um conversation_id pode ser um telefone, um e-mail ou o id do WhatsApp do cliente, então toda leitura que o leva tem uma forma POST, com o id no corpo: O Console e os SDKs usam as formas POST das leituras que fazem. As formas GET continuam na /v1; se você usar uma delas, mande um id de conversa opaco do seu sistema.

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

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.

A memória nunca corta

Os tamanhos acima são de um pedido: um pedido maior é recusado com erro, nunca aceito pela metade. O que entra, a memória guarda e aprende inteiro, e não apaga sozinha:
  • Um turno, um e-mail ou um documento longo é lido em partes, em ordem e com sobreposição, nunca cortado no começo, no fim ou em N caracteres. Um arquivo é lido inteiro, em janelas de 50 páginas, e um texto acima de 100 mil caracteres vira vários turnos, cada um com a parte dele (eventos).
  • Resumos, soluções, valores, pendências, instruções, notas dos agentes e vínculos são guardados inteiros, sem teto de quantidade.
  • Um lote que falha em todas as tentativas fica guardado e pode ser tentado de novo.
  • O que sai da memória sai pelo apagamento pedido pelo titular e pela retenção que o espaço configura, e os dois alcançam tudo, inclusive os lotes guardados.
Só uma leitura tem tamanho: o bloco que vai para o agente. Quando ele deixa algo de fora, diz quanto e onde está o resto: left_out no bloco de notas, omitted no bloco de restrições, open_objects_more no pacote de transferência, partial num campo derivado, “mais N objetos deste cliente fora desta lista” e “mais N registros (consulte o histórico)” nas linhas do contexto, “(continua no histórico)” num texto longo citado, e um cursor nas listas que vêm por página. O resto está na busca e na abertura do histórico.

Velocidade

Nenhum LLM roda no caminho do context() nem da navegação. Os tempos medidos na região estão no benchmark.

Tetos iniciais de um espaço

São os tetos de cada espaço hoje. 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

Erros

cada código e o que fazer com ele.

Eventos e o lote

idempotência e erro por item na prática.

Espaços e chaves

escopos, fontes e o formato da chave.

A API da Niadra

todas as rotas, geradas do OpenAPI.