@niadra/sdk é o SDK de TypeScript. Roda no Node 18 ou mais novo e em runtimes de borda, precisa só de fetch e vem em ESM e CommonJS, com as definições de tipo completas. É de código aberto, sob Apache 2.0. Cada método desta página corresponde a uma rota da referência da API.
Instalação
O cliente
enabled é false quando o cliente foi criado sem chave utilizável; ele então não manda nada. Crie um cliente por processo e compartilhe: ele é dono da fila, do cache e das conexões.
Seguro por padrão, estrito quando você pede
Por padrão, todo método segue em frente quando algo falha. As leituras resolvem com resultado vazio,track() devolve null para um item que não pôde aceitar, e o motivo vai para o log. Os logs levam status, código de erro e id da requisição, nunca handle, texto de mensagem nem a chave. Com strict: true, o construtor lança erros de configuração, track() lança erros de validação, as leituras lançam erros de requisição e flush() lança os lotes perdidos.
Tempo máximo
timeouts, ou por chamada com { timeout }. Passe { signal } para cancelar uma chamada. As leituras só são repetidas no 421 (o espaço mudou de célula), na hora, até três tentativas. As escritas são repetidas no 408, 421, 429 e 5xx, com espera exponencial e variação aleatória; as outras respostas 4xx nunca são repetidas.
O cache de contexto
Dentro de uma conversa ou tarefa, os contextos ficam em memória:- com menos de 10 s: devolvidos sem requisição;
- até 10 minutos mais velhos: devolvidos na hora, enquanto uma requisição em segundo plano atualiza;
- quando uma requisição falha: o último contexto bom, se tiver menos de 30 minutos;
- no máximo 1.000 contextos, saindo primeiro o usado há mais tempo.
not_modified em vez do texto inteiro, e só uma atualização por contexto roda de cada vez. Um 401 ou 403 não é indisponibilidade: os contextos guardados saem (todos no 401, o pedido no 403), então cortar o acesso de um fornecedor corta também o que ele tinha em cache. Uma leitura comum e uma leitura com delta da mesma conversa dividem a mesma entrada, e cada delta é entregue uma vez só.
A fila de escrita
track() e action() voltam na hora. Os eventos saem em lote: quando 15 estão esperando ou a cada segundo, até 100 por requisição, com três tentativas cada. Com 10.000 eventos esperando, os novos são descartados e registrados no log.
Handles
Um handle identifica um sujeito num canal ou sistema. Os construtores definem o tipo e o escopo; o servidor normaliza o valor.
Os construtores de pessoa aceitam
{ subjectKind } opcional para marcar uma organização. toObjectRef("invoice:erp:0823") transforma a forma curta num ObjectRef; o id pode ter dois-pontos.
context()
O contexto de uma pessoa, de uma organização ou de um objeto de negócio. Corresponde aPOST /v1/context.
options aceita timeout, signal, headers (como um traceparent) e cache: false, para pular o cache nesta chamada.
Resolve com um ContextResult, sempre utilizável:
renderSuffix(response) e renderLive(response) montam o mesmo sufixo a partir de uma resposta crua.
search()
Busca no histórico inteiro de um sujeito, por palavra e por significado. Corresponde aPOST /v1/history/search.
Toda chamada de navegação resolve com um
Result: { data, error }, com exatamente um dos dois preenchido. data traz items, recurrence, withheld, as_of, tokens_used e degraded.
timeline()
Uma página do histórico do sujeito, do mais recente para o mais antigo. Corresponde aPOST /v1/history/timeline.
subject, about, filters, cursor, limit (de 1 a 100, padrão 20), verification e conversation_id. data traz items, next_cursor, withheld e as_of.
open()
Abre um item do histórico vindo desearch() ou timeline(). Corresponde a GET /v1/history/items/{item_id}.
params aceita verification, conversation_id e task_id. O trecho literal, excerpt, só volta para chaves com escopo elevado.
objectState() e objectTimeline()
Leituras de um objeto de negócio. Correspondem aGET /v1/objects/{object_type}/{namespace}/{external_id} e à linha do tempo dele.
limit vai de 1 a 100, padrão 20.
track()
Registra uma mensagem, um evento de sistema ou uma ação. Volta na hora com a chave de idempotência do item, ounull quando o item foi descartado. Corresponde a POST /v1/batch.
action()
Registra o que um agente fez num sistema de registro. Vai para a fila, comotrack(); registrar ação exige o escopo act.
ActionEvent aceita os mesmos campos de track() e mais operation (obrigatório, como credit), result (até 2.000 caracteres), purpose, closes (a pendência que a ação cumpre, por item_id ou por object e operation) e corrects_action_id. speaker é ai_agent por padrão. A ação fica declared até o sistema de registro confirmar.
identify(), verify() e handoff()
Esses três saem na hora, sem fila, e resolvem com umWriteResult: { ok: true, idempotency_key, error: null } ou { ok: false, idempotency_key, error }. Um context() feito depois que identify() ou verify() resolveu já enxerga a mudança.
Um nível em
verify() acima do teto da fonte falha com verification_not_allowed.
feedback()
Corrige o que a Niadra derivou sobre um sujeito. Sai na hora e vira evento, então é auditado como qualquer outro. Corresponde aPOST /v1/feedback.
subject é sempre obrigatório; value vai até 2.000 caracteres e reason até 500.
uploadMedia()
Entrega um arquivo à Niadra, como a gravação de uma ligação, e resolve com a referência para o evento. Mídia nunca viaja dentro do evento. Corresponde aPOST /v1/media/uploads.
upload_headers que a API devolveu, que são os cabeçalhos cobertos pela assinatura, e nada além: nunca a sua chave nem os defaultHeaders. A URL precisa ser HTTPS, a não ser contra um endpoint local servido por HTTP. O armazenamento confere o corpo contra o tamanho e o hash declarados. Com subject, o arquivo fica guardado sob aquela pessoa, então apagar a pessoa apaga o arquivo, mesmo que nenhum evento o cite. No Node 18, Web Crypto só existe atrás de uma flag.
data traz media_ref, media_sha256, content_type, size_bytes e expires_at.
conversation()
Um ajudante para a conversa com um cliente: lê o contexto que o servidor fixa, guarda os deltas, captura os turnos e encerra a conversa.
Depois do primeiro contexto, cada leitura pede também o delta, e a conversa guarda cada delta que chega, em ordem, no
suffix, antes dos turnos ao vivo. Quando o servidor fixa um contexto novo, depois de verify() por exemplo, os deltas guardados saem: o contexto novo já os contém. Uma leitura com query é avulsa e não mexe neles. Chame markInjected() toda vez que puser o contexto num prompt: é assim que a Niadra distingue um contexto que chegou depois de o agente falar de um contexto que o agente tinha e não usou.
task()
O mesmo para um agente interno (cobrança, recuperação de crédito, triagem). Uma tarefa centra o contexto no objeto dela, guarda deltas e carimbos como uma conversa, delimita o cache e termina comtask.ended.
TaskParams aceita channel (obrigatório, o agente interno ou o sistema, como billing-agent), task_id (um UUIDv7 quando não vem), subject, object, about, view (padrão brief; use uma view de tarefa como task:billing), verification e target. Uma tarefa tem context(), markInjected(), agent(), track(), action(), verify(), tools() (null sem sujeito) e end().
tools()
O kit de navegação como ferramentas de chamada de função, com o cliente amarrado no SDK e não nos argumentos da ferramenta. O modelo escolhe o que procurar, nunca de quem, então uma injeção de prompt não tem argumento para trocar de cliente.binding aceita about, verification, conversation_id, task_id e voice (usa o tempo máximo da voz).
TOOL_DEFINITIONS e TOOL_NAMES também são exportados. Para APIs que esperam { name, description, input_schema }, leve function.parameters para input_schema. As definições também saem em GET /v1/history/tools.
subjectToken()
Emite um token assinado, válido por 15 minutos, que amarra um cliente, uma conversa e um nível de verificação. Chame do seu backend e entregue à conexão MCP. Corresponde aPOST /v1/subject-tokens.
params aceita subject, about, conversation_id, task_id e verification. data traz token e expires_at. Mande o token no cabeçalho Niadra-Subject-Token, junto da chave da fonte. Veja MCP com qualquer LLM.
wrap()
Embrulha um cliente compatível com a OpenAI para toda chamada receber o contexto e registrar a resposta.chat.completions.create e chat.completions.parse pelo embrulho, com streaming ou sem, recebe o contexto depois das suas mensagens de sistema iniciais e o sufixo no fim. A injeção é carimbada, e a resposta do modelo (a primeira escolha) é registrada como turno do agente: na hora, ou quando o stream termina ou você para de ler. .withResponse() continua funcionando e também registra; .asResponse() devolve a resposta HTTP crua, então nada é registrado nesse caso. Passe uma função em vez de uma sessão para escolher uma a cada chamada; quando ela devolve null, a chamada passa intacta. Nada do que o embrulho faz derruba a sua chamada: um contexto que não chega fica de fora, e uma falha ao registrar a resposta vai para o log, sem conteúdo. injectContext(context, messages) faz só o posicionamento, sem embrulhar.
flush() e shutdown()
flush() manda todo evento da fila. Chame antes de uma função serverless retornar, ou entregue à plataforma nos runtimes de borda (ctx.waitUntil(niadra.flush())). shutdown() esvazia a fila, para o temporizador de fundo e libera o gancho de saída; chame no seu tratador de SIGTERM em serviços de longa duração, porque beforeExit não dispara com sinais nem com process.exit().
Erros
Todo erro estendeNiadraError.
O catálogo completo de códigos está em Erros. Mande o
requestId quando falar com o suporte.
Próximos passos
SDK de Python
A mesma superfície, síncrona e assíncrona.
Início rápido
Da chave ao primeiro contexto entregue.
MCP com qualquer LLM
Sete ferramentas com o cliente amarrado por subject_token.
Erros
O catálogo de códigos e o que fazer com cada um.

