@aronline/sdk
v0.3.0
Published
SDK oficial da API do AR Online (/v3)
Readme
AR Online SDK para TypeScript
Cliente oficial da API da AR Online para TypeScript e JavaScript.
Sobre a AR Online
A AR Online é uma plataforma brasileira de notificação eletrônica com validade jurídica. Uma única requisição dispara a notificação em até cinco canais, e cada etapa do percurso — envio, entrega e leitura — é registrada com carimbo do tempo emitido por uma Autoridade de Carimbo do Tempo da ICP-Brasil. Esse registro é o que dá à comunicação o valor de prova documental previsto na MP 2.200-2/2001, e é o que diferencia a plataforma de um serviço comum de disparo de mensagens.
Os canais disponíveis são:
| canal | o que é | | --- | --- | | AR-Email | e-mail com comprovação de entrega e de leitura | | AR-SMS | mensagem de texto para o celular do destinatário | | AR-WhatsApp | notificação por WhatsApp | | AR-Voz | chamada telefônica automatizada | | AR-Cartas | carta física registrada, enviada pelos Correios |
Você escolhe quais canais usar em cada envio. O processamento é assíncrono: a API confirma o recebimento na hora e devolve um identificador, que você usa depois para consultar o status de cada canal e baixar os comprovantes.
| | | | --- | --- | | Site | https://www.ar-online.com.br | | Documentação da API | https://docs.ar-online.com.br | | Suporte | [email protected] · +55 (11) 4200-7766 |
Requisitos
- Node.js 20 ou mais novo
- Nenhuma dependência de produção: o SDK usa o
fetchda própria plataforma
Instalação
npm install @aronline/sdkO pacote é distribuído como ESM, com os tipos incluídos.
Autenticação
A plataforma tem duas superfícies de API, e cada uma usa uma credencial diferente. O SDK aceita as duas no mesmo cliente e envia cada uma no formato que a sua superfície espera.
Token do gateway (API legada)
É a credencial que você usa para enviar notificações e consultar status hoje.
Solicite em [email protected]. No SDK, ela vai em legacyToken.
Token da API /v3
Solicite em [email protected]. O token fica preso a uma entidade da sua conta, e é ela que define quais dados ele enxerga — se você precisa consultar mais de uma, peça um token para cada. O padrão é somente leitura.
O token tem prazo de validade. Token ausente, expirado ou revogado responde
401; se um token vazar, peça a revogação e ele deixa de ser aceito na chamada
seguinte.
A /v3 ainda não está publicada. O endereço
v3.ar-online.com.br, que é o padrão do SDK para essa superfície, entra no ar junto com ela — assim como a emissão de token por conta própria, com o mesmo usuário e senha do portal. Até lá, a parte da /v3 deste SDK serve para desenvolver contra um ambiente de teste, e é oclient.legacyque fala com a API em produção.
Primeiros passos
O envio de notificações é feito hoje pela API legada, exposta no SDK em
client.legacy:
import { Client } from '@aronline/sdk';
const client = new Client({ legacyToken: process.env.AR_GW_TOKEN });
const { idEmail } = await client.legacy.send({
nameTo: 'João da Silva',
to: '[email protected]',
subject: 'Notificação de vencimento',
content: '<p>Prezado João, identificamos uma pendência em seu contrato.</p>',
sms: { number: '11999998888' },
});
console.log('notificação aceita:', idEmail);Guarde o idEmail: é com ele que você consulta o status de qualquer canal e
baixa os comprovantes.
const status = await client.legacy.status.email(idEmail);
console.log(status.description); // 'Processado', 'Enviado', 'Entregue', 'Lido'Referência
Envio e acompanhamento (client.legacy)
| método | o que faz |
| --- | --- |
| legacy.send(envio) | envia a notificação em um ou mais canais |
| legacy.status.email(id) | status do AR-Email |
| legacy.status.sms(id) | status do AR-SMS |
| legacy.status.whatsapp(id) | status do AR-WhatsApp |
| legacy.status.voz(id) | status do AR-Voz |
| legacy.status.carta(id) | status do AR-Cartas, com o rastreio dos Correios |
| legacy.status.full(id) | dados de perícia de todos os canais numa chamada |
| legacy.sendingProof(id) | comprovante de envio em PDF |
| legacy.laudo(id) | laudo pericial em PDF |
| legacy.finalizarRegua(id) | encerra a régua de notificação do envio |
| legacy.templates.list(filtro?) | lista os modelos da sua entidade |
| legacy.templates.get(id) | busca um modelo |
| legacy.templates.update(id, campos) | edita nome e compartilhamento |
| legacy.templates.deactivate(id) | desativa um modelo |
| legacy.templates.setStatus(id, ativo) | ativa ou desativa um modelo |
Envio multicanal: cada canal é um bloco opcional no corpo.
await client.legacy.send({
nameTo: 'João da Silva',
to: '[email protected]',
subject: 'Notificação de vencimento',
content: '<p>Conteúdo em HTML.</p>',
customID: 'contrato-4471', // sua referência, devolvida na consulta de status
attachments: [{ name: 'contrato.pdf', base64: '…' }],
sms: {
number: '11999998888',
typeSend: '1', // '1' só se o e-mail não for entregue; '2' sempre
customMessage: 'Você recebeu um AR-Email. Acesse: {SHORT_LINK}',
},
whatsapp: { number: '11999998888', variables: { template: 'aviso_01' } },
voz: { number: '1133334444', template: 'aviso_voz' },
carta: { name: 'João da Silva', modelo: 'padrao' },
});Comprovantes: o comprovante de envio chega em base64 dentro de um JSON e o SDK já o decodifica; o laudo pericial chega como PDF binário.
import { writeFile } from 'node:fs/promises';
const comprovante = await client.legacy.sendingProof(idEmail);
if (comprovante.pdf !== null) {
await writeFile('comprovante.pdf', comprovante.pdf);
} else {
console.log(comprovante.message); // ainda sem status de entrega
}
await writeFile('laudo.pdf', await client.legacy.laudo(idEmail));Consultas da API /v3 (client.*)
A /v3 é a API nova, com contrato limpo e validação estrita. Hoje ela é somente de leitura.
| método | o que faz | precisa de token |
| --- | --- | --- |
| templates.list(filtro?) | lista os modelos, com filtro por canal | sim |
| templates.get(id) | busca um modelo pelo UUID | sim |
| tags.list() · tags.get(id) | suas etiquetas | sim |
| allowlist.list() | seus destinatários permitidos | sim |
| freshness.get() | o atraso da carga de dados | sim |
| version.get() | qual versão da API está no ar | não |
const client = new Client({ token: process.env.AR_TOKEN });
const modelos = await client.templates.list({ channel: 'whatsapp' });O filtro channel aceita email, sms, whatsapp, voice e letter, e o
TypeScript recusa qualquer outro valor em tempo de compilação. A constante
CHANNELS traz a mesma lista em tempo de execução.
Etiquetas e lista de permitidos são recursos pessoais: respondem o que
pertence a quem está no token. Um token de integração, que não representa uma
pessoa, recebe 403 nessas duas rotas.
Tratamento de erros
Chamada que não lançou exceção deu certo. Você não precisa ler status HTTP nem procurar campo de erro no corpo da resposta.
A /v3 lança ApiError:
import { ApiError } from '@aronline/sdk';
try {
await client.templates.get('nao-existe');
} catch (error) {
if (error instanceof ApiError) {
console.error(error.code); // 'not_found'
console.error(error.status); // 404
console.error(error.requestId); // informe este número ao abrir um chamado
}
}| propriedade | conteúdo |
| --- | --- |
| status | o status HTTP (0 quando a API não foi alcançada) |
| code | o código do catálogo: not_found, forbidden, rate_limited, … |
| message | a mensagem da API, em português |
| requestId | identifica a chamada nos nossos registros |
| field | o campo recusado, quando a recusa é sobre um campo |
| details | uma entrada por campo, em erro de validação |
| retryAfterSeconds | quantos segundos esperar, em 429 e 503 |
| retryable | true em 429 e 503 |
A API legada lança LegacyApiError, com os campos do contrato antigo:
| propriedade | conteúdo |
| --- | --- |
| status | o código que vale, mesmo quando o HTTP respondeu 200 |
| httpStatus | o status que veio no protocolo |
| body | o corpo da resposta, exatamente como chegou |
O SDK não repete chamadas automaticamente, porque só quem chamou sabe se a operação pode acontecer duas vezes. Quando quiser repetir:
if (error instanceof ApiError && error.retryable) {
await new Promise((r) => setTimeout(r, (error.retryAfterSeconds ?? 5) * 1000));
}Configuração do cliente
const client = new Client({
token: process.env.AR_TOKEN, // credencial da /v3
legacyToken: process.env.AR_GW_TOKEN, // credencial do gateway
baseUrl: 'https://v3.ar-online.com.br', // padrão
legacyBaseUrl: 'https://api.ar-online.com.br', // padrão
timeoutMs: 30_000, // padrão, vale para as duas superfícies
});Cada credencial é opcional: informe só a da superfície que você vai usar. Os endereços podem ser trocados para apontar a um ambiente de teste.
Os objetos devolvidos usam os nomes de campo como a API os escreve
(provider_identifier, created_at, customID). Não há camada de conversão de
nomes, para que o que você lê no SDK seja o mesmo que você vê na documentação da
API e nos nossos registros de suporte.
Webhooks
Em vez de consultar o status repetidamente, você pode receber uma chamada POST
a cada mudança. A configuração é feita com o suporte, que cadastra o seu endpoint
e os parâmetros de autenticação. O SDK não recebe a requisição por você, mas
exporta os tipos do payload:
import type { WebhookPayloadV1, WebhookPayloadV2 } from '@aronline/sdk';Veja https://docs.ar-online.com.br/webhooks/visao-geral para o fluxo completo, incluindo a política de retentativas.
As duas superfícies, e o caminho entre elas
A API legada é a que está em produção hoje e concentra envio, status e comprovantes. A /v3 é a API nova, para onde as funcionalidades estão sendo migradas aos poucos.
Quando uma rota ganha equivalente na /v3, o método correspondente de
client.legacy passa a falar com a /v3 internamente, sem mudar de
assinatura. Na prática, você migra atualizando o pacote, não reescrevendo a
sua integração. Cada troca dessas é registrada no CHANGELOG.
Desenvolvimento
npm install
npm run verifyverify roda o portão inteiro:
| comando | o que cobra |
| --- | --- |
| npm run typecheck | tsc estrito, com exactOptionalPropertyTypes |
| npm run lint | ESLint com strictTypeChecked |
| npm run format:check | Prettier |
| npm run spell | codespell |
| npm run test:coverage | vitest, reprovando abaixo de 95% de linhas |
| npm run build | o dist/ que é publicado |
| npm run audit | npm audit, reprovando de moderate para cima |
| métrica | valor | | --- | --- | | Testes | 74 | | Cobertura de linhas | 99,4% | | Dependências de produção | 0 | | Vulnerabilidades conhecidas | 0 |
Os testes sobem um servidor HTTP real em uma porta livre e falam com ele por
fetch, em vez de substituir o fetch por um dublê. O que o SDK precisa acertar
é o comportamento na rede: qual rota embrulha a resposta, como a recusa volta e o
que acontece quando algo que não é a API responde.
Para publicar uma versão, veja PUBLICANDO.md.
Suporte
- Dúvidas de integração e emissão de credenciais: [email protected]
- Telefone: +55 (11) 4200-7766
- Defeitos neste SDK: issues do repositório
Ao abrir um chamado sobre uma chamada que falhou, informe o requestId do erro:
é com ele que localizamos a requisição nos nossos registros.
Licença
Apache License 2.0 — veja LICENSE.
© 2026 AR ONLINE TECNOLOGIA LTDA.
