ONRTDPJ Análise de documentos por IA

Integrar a análise de documentos por IA

O cartório mantém o sistema que já tem. Esta API lê o documento e devolve a ficha extraída, os achados e o checklist respondido — ela não registra, não sela e não lavra.

Ler no navegador
Swagger · referência das rotas

Cada rota com todos os campos de entrada e de resposta, e o botão para disparar uma chamada sem sair da página. É por onde se tira dúvida de campo.

Sai do mesmo metadado que define as rotas — também em openapi.json, para gerar o cliente.
Rodar na sua máquina
Postman · coleção pronta

As sete chamadas na ordem, do token ao resultado, com as variáveis já encadeadas: o que uma devolve, a seguinte usa. É por onde se faz a primeira análise.

Importe junto o environment do ambiente em que vai trabalhar: a
tabela de ambientes está logo abaixo.

O caminho inteiro, de uma vez

1 · uma vez
Credencial
Você gera um par de chaves. O Console Nacional cadastra a pública.
2 · uma vez
Autorização
O cartório libera sua empresa e define o teto diário — ou o Console Nacional por ele.
3 · a cada 10 min
Token
Você assina uma asserção com a privada e troca por um token.
4
Preparar
Peça a URL de envio. O arquivo não passa por nós.
5 · direto
PUT no armazenamento
Seu sistema fala com o bucket. Sem intermediário.
6
Confirmar
Conferimos tamanho e formato. Só então o arquivo existe.
7
Pedir a análise
Resposta 202 com o id. O crédito é separado agora.
8
Receber
Webhook, se cadastrado. Ou consulta — as duas funcionam.

A caixa tracejada é a única em que seu sistema não fala conosco: ele fala direto com o armazenamento.

Antes de qualquer código

Você precisa de três coisas do lado de cá, e todas são pedidas ao ONRTDPJ uma única vez: a sua empresa cadastrada com a chave pública, a autorização do cartório (que define o teto diário e, se quiser, o endereço do webhook) e crédito de IA na conta daquela serventia — sem saldo a análise é recusada mesmo com tudo o mais pronto.

⏰ O relógio da sua máquina — a causa nº 1 de "credencial inválida"

A asserção vale por pouquíssimo tempo (recomendado 120 s, teto de 300 s), e o servidor compara o exp com o horário real dele, em UTC, tolerando só 60 segundos de diferença. O iat/exp são unix timestamp — são UTC por definição, não dependem do fuso do seu Windows; o que importa é o relógio absoluto da máquina estar certo. Se ele estiver atrasado, a asserção chega expirada; se estiver adiantado, chega com vida longa demais — e nos dois casos a resposta é credencial inválida, levando você a procurar defeito na chave e no cadastro, que estão certos. É também o que faz "funcionar na segunda tentativa".

Antes de depurar qualquer coisa: abra time.is na máquina que gera a asserção. Se acusar mais de ~30 s de diferença, sincronize o relógio (Windows: Data e hora → Sincronizar agora; deixe o fuso em automático) e teste de novo. Use validade de 120 s e gere-e-troque o token na sequência, sem deixá-lo esfriar.

Os ambientes

O que muda de um para o outro é só o endereço. O caminho das rotas, os campos e a audiência da asserção são os mesmos em todos.

AmbienteEndereçoO que éSwaggerPostman
Local http://localhost:3100 A stack rodando na sua máquina — é a porta da borda, não a do serviço. abrir baixar
Homologação https://iah.rtdbrasil.org.br O ambiente de testes do ONRTDPJ. É onde você exercita a integração antes de valer. abrir baixar
Produção https://ia.rtdbrasil.org.br O ambiente de produção do ONRTDPJ — onde a integração passa a valer. abrir baixar
Como alternar sem errar de ambiente

No Postman, importe os environments acima (um clique cada) e troque pelo seletor do canto superior direito. A coleção fala apenas {{host}} — não edite o endereço dentro dela. Com o endereço escrito na coleção, disparar contra o ambiente errado fica a uma distração de distância.

Fora do Postman, a mesma ideia: o endereço é a única coisa que sua configuração precisa trocar.

1 · Autenticação

Prefere ver funcionando antes de ler? No fim desta seção há duas ferramentas que rodam nesta página: uma gera um par de chaves, a outra assina a asserção e pede um token de verdade. Dois minutos, sem instalar nada.

Primeiro: gere o seu par de chaves

Quem gera é você, na sua máquina, e a privada nunca sai dela — nem para nós. É o que faz um vazamento do nosso banco não virar acesso ao cartório de ninguém: o que guardamos é a metade que não assina nada. Nós nunca pedimos, nunca recebemos e não temos onde guardar uma chave privada.

Dois comandos, e qualquer um dos dois serve. A curva é P-256 (para ES256):

# com openssl — dois arquivos, privada e pública
openssl ecparam -genkey -name prime256v1 -noout -out privada.pem
openssl ec -in privada.pem -pubout -out publica.pem

# a pública em JWK, que é o formato que a tela do cadastro pede
node -e "console.log(JSON.stringify(require('crypto').createPublicKey(require('fs').readFileSync('publica.pem')).export({format:'jwk'})))"
# só com Node, sem openssl — gera o par e imprime a pública em JWK
node -e "const c=require('crypto');const {publicKey,privateKey}=c.generateKeyPairSync('ec',{namedCurve:'P-256'});
require('fs').writeFileSync('privada.jwk.json',JSON.stringify(privateKey.export({format:'jwk'})));
console.log(JSON.stringify(publicKey.export({format:'jwk'})))"
O que se entrega, e o que não se entrega

Entregue ao ONRTDPJ só a JWK pública — ela tem kty, crv, x e y. Se o que você copiou tem d, p ou q, é a PRIVADA: a tela do cadastro recusa e diz por quê, mas a essa altura ela já saiu da sua máquina — gere outro par e descarte esse.

Escolha um kid que diga onde a chave vive (producao-2027, homologacao-2026). É por ele que o servidor sabe qual das suas chaves confere a assinatura, e é o que permite trocar de chave sem parar a integração: cadastra-se a nova, vira-se o kid nas asserções, e só então revoga-se a antiga.

Os valores que o ONRTDPJ lhe entrega

São quatro, e todos estão numa tela só — Cartórios › a serventia › API de análise por IA › Dados para quem vai integrar, com botão de copiar. Peça-os a quem administra o cartório:

ValorOnde entra
id da sua empresaiss e sub da asserção — sai do cadastro da empresa
identificador da serventiao campo cns do pedido de token
audiênciaaud da asserção — é um identificador, não um endereço que se chama
endereço baseo começo de toda URL desta API

Não há senha nem chave fixa. Você assina uma asserção (um JWT curto) com a sua chave privada e a troca por um token de acesso de 10 minutos. Quem guarda segredo é você; nós guardamos só a sua chave pública, e por isso um vazamento do nosso lado não dá acesso a ninguém.

A asserção que você assina

CampoO que vai
isso id da sua empresa integradora (o que o Console Nacional lhe deu)
subo mesmo valor de iss
auda URL desta porta de token — o valor exato está na referência
jtiidentificador único da asserção; repetir um já usado é recusado
expcurto: ela vale para UMA troca, não para o dia
kid (cabeçalho)qual das suas chaves assinou
alg (cabeçalho)ES256 ou RS256

Como assinar a asserção, linha a linha

Um JWT são três pedaços separados por ponto: cabeçalho, corpo e assinatura. Os dois primeiros são JSON codificado em base64url — que é o base64 comum com + virando -, / virando _ e sem os = do fim. A assinatura é feita sobre o texto cabeçalho.corpo, e entra como terceiro pedaço.

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Li4ufQ    ← cabeçalho
.eyJpc3MiOiIuLi4iLCJzdWIiOiIuLi4iLCJhdWQiOiIuLi4ifQ   ← corpo
.MEUCIQD...                                            ← assinatura
A armadilha do ES256 — leia antes de depurar

O JOSE exige a assinatura em formato cru (os dois números R e S, 32 bytes cada, colados). A maioria das bibliotecas de criptografia devolve DER por padrão, que é outro empacotamento dos mesmos números. As duas são "a assinatura certa", e só uma passa: com DER a verificação recusa, e o erro chega como credencial inválida — o que leva a procurar defeito na chave, no kid e no cadastro, que estão todos certos. Em Node isso é a opção dsaEncoding: 'ieee-p1363'; em Python, o PyJWT já faz certo sozinho.

Em Node, sem biblioteca nenhuma

const { createSign, createPrivateKey, randomUUID } = require('node:crypto');
const fs = require('node:fs');

const INTEGRADOR = '';
const KID        = '';
const AUD        = '';
const SERVENTIA  = '';
const BASE       = '';

const b64u = (x) => Buffer.from(x).toString('base64url');

function assinarAssercao() {
  const chave = createPrivateKey({
    key: JSON.parse(fs.readFileSync('privada.jwk.json')), format: 'jwk',
  });
  const agora  = Math.floor(Date.now() / 1000);
  const cab    = { alg: 'ES256', typ: 'JWT', kid: KID };
  const corpo  = {
    iss: INTEGRADOR, sub: INTEGRADOR, aud: AUD,
    jti: randomUUID(),      // único a cada troca — repetir é recusado
    iat: agora, exp: agora + 120,
  };
  const entrada = `${b64u(JSON.stringify(cab))}.${b64u(JSON.stringify(corpo))}`;
  const assin = createSign('SHA256').update(entrada).end()
    .sign({ key: chave, dsaEncoding: 'ieee-p1363' });   // ← cru, não DER
  return `${entrada}.${assin.toString('base64url')}`;
}

async function pegarToken() {
  const r = await fetch(`${BASE}/token`, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ client_assertion: assinarAssercao(), cns: SERVENTIA }),
  });
  if (!r.ok) throw new Error(`token recusado: ${r.status} ${await r.text()}`);
  const { access_token } = await r.json();
  return access_token;      // vale 10 minutos
}

Em Python, com PyJWT

import time, uuid, json, jwt, requests
from cryptography.hazmat.primitives.serialization import load_pem_private_key

CHAVE = load_pem_private_key(open('privada.pem','rb').read(), password=None)

def assinar():
    agora = int(time.time())
    return jwt.encode(
        {'iss': INTEGRADOR, 'sub': INTEGRADOR, 'aud': AUD,
         'jti': str(uuid.uuid4()), 'iat': agora, 'exp': agora + 120},
        CHAVE, algorithm='ES256', headers={'kid': KID},
    )

def pegar_token():
    r = requests.post(f'{BASE}/token',
                      json={'client_assertion': assinar(), 'cns': SERVENTIA})
    r.raise_for_status()
    return r.json()['access_token']
Renovar, e quando renovar

Não há refresh token. O token vale 10 minutos; para renovar, assina-se uma asserção NOVA — com jti novo — e troca-se de novo. É a mesma chamada, e é barata.

Na prática: guarde o token em memória com a hora em que ele vence e troque quando faltar menos de um minuto. Não guarde em disco nem em banco — em dez minutos ele não vale mais, e um token guardado é um segredo a mais para vazar. Se um pedido voltar 401, troque por um token novo e repita o pedido uma vez; se voltar 401 de novo, o problema é a autorização, não o token, e repetir não resolve.

A troca

POST /integracao/ia/v1/token
{
  "client_assertion": "<o JWT que você acabou de assinar>",
  "cns": "<o IDENTIFICADOR da serventia — NÃO o número do CNS>"
}

→ 200 { "access_token": "...", "token_type": "Bearer", "expires_in": 600, "scope": "analise:ler" }

Use o token em Authorization: Bearer <access_token>. Ele carrega a serventia: nenhuma rota abaixo pergunta de qual cartório é o pedido, e mandar isso no corpo é recusado — é o que impede o integrador legítimo de um cartório de ler os documentos de outro.

Experimente aqui, sem instalar nada

As duas caixas abaixo fazem, dentro desta página, exatamente o que os exemplos acima fazem em Node e em Python — e servem para a coisa mais útil que existe ao integrar uma API assinada: ter um resultado certo para comparar com o seu. Quando a sua implementação voltar credencial inválida, assine a mesma asserção aqui e veja onde as duas diferem.

Gerar um par aqui, agora

Roda no seu navegador, com crypto.subtle. Nada sai desta aba — a privada aparece só na tela, e some quando você fechar. Para teste. Em produção, gere a chave na máquina que vai assinar, com os comandos acima.

Assinar a asserção e trocar pelo token

Preencha com os valores que o Console lhe deu (o botão Credenciais, na ficha do cartório ou na da empresa, traz todos). A asserção é assinada aqui; o token é pedido à API deste mesmo ambiente.

2 · O de/para das naturezas

A análise é pedida pelo código de natureza do nosso catálogo. A correspondência com o código do seu sistema é mantida por você: nós não guardamos essa tabela, e é de propósito — uma tradução mantida do nosso lado seria uma segunda cópia do seu catálogo, desatualizando em silêncio.

GET /integracao/ia/v1/naturezas

→ 200 {
  "uf": "MG",
  "atualizadoEm": "2026-09-28T13:00:00.000Z",
  "naturezas": [
    { "codigo": "LOCACAO_PREDIO", "rotulo": "Contrato de locação de prédio",
      "naturezaMaeCodigo": null, "especialidade": "RTD",
      "conteudoFinanceiroObrigatorio": true,
      "posicoesJuridicasMinimas": ["LOCADOR", "LOCATARIO"] },
    { "codigo": "NOTIFICACAO_INDIVIDUAL", "rotulo": "Notificação extrajudicial · individual",
      "naturezaMaeCodigo": "NOTIFICACAO", "especialidade": "RTD",
      "conteudoFinanceiroObrigatorio": false,
      "posicoesJuridicasMinimas": ["NOTIFICANTE", "NOTIFICADO"] }
  ]
}

3 · O envio do documento

O arquivo não passa pela nossa aplicação. Pedimos que você o mande direto ao armazenamento, com uma autorização curta para uma única chave. É o que permite contrato escaneado de quarenta páginas sem prender um processo que atende o balcão ao mesmo tempo.

1) POST /integracao/ia/v1/arquivos/preparar   { "nome": "contrato.pdf", "tamanho": 2400000 }
   → 200 { "arquivoId": "...", "url": "https://...", "metodo": "PUT",
           "expiraEm": "...", "tetoBytes": 314572800 }

2) PUT <url>  (o corpo é o arquivo; esta chamada NÃO passa por nós)

3) POST /integracao/ia/v1/arquivos/{arquivoId}/confirmar
   → 200 { "arquivoId": "...", "nome": "...", "mime": "application/pdf",
           "tamanho": 2400000, "sha256": "..." }
Campo do preparoObrigatórioObservação
nomesim com extensão — é dela que sai o primeiro sinal do formato
tamanhonão serve para recusar cedo o que já se sabe grande demais; não é acreditado — a confirmação pergunta ao armazenamento qual foi o tamanho real
Depois de confirmar, a leitura roda sozinha — e você NÃO espera por ela

Transcrever um PDF digitalizado leva dezenas de segundos, e as quatro chamadas acima levam segundos. Peça a análise assim mesmo. Se a leitura ainda não terminou, a análise nasce aguardando_ocr e entra na fila sozinha quando o texto ficar pronto.

Não implemente uma espera fixa antes de pedir: ela funciona na sua máquina e quebra no documento grande do seu cliente. Se quiser acompanhar o passo, existe GET /integracao/ia/v1/arquivos/{id} — mas é opcional, e o aviso arquivo.pronto chega sozinho para quem cadastrou webhook.

Em que pé está a leitura (opcional)

GET /integracao/ia/v1/arquivos/{arquivoId}

→ 200 { "arquivoId": "...", "nome": "contrato.pdf",
        "leitura": "pendente" | "concluida" | "falhou",
        "paginas": 11, "temAssinatura": null, "assinaturas": [] }

O campo se chama leitura, e não situacao, de propósito: situacao já é da ANÁLISE, e dois campos com o mesmo nome e significados diferentes na mesma API é como se confunde quem integra. E temAssinatura vem null — e não false — enquanto não houve leitura: ausência de leitura não é ausência de assinatura.

4 · Pedir a análise

Duas coisas que economizam o seu primeiro dia

Repetir o mesmo pedido não cria outra análise. Enquanto o mesmo arquivo estiver aguardando_ocr, na_fila ou analisando, você recebe de volta a MESMA análise, com o mesmo id e sem custo novo. Repetição de chamada de rede é normal e não pode cobrar duas vezes.

Você pode mandar o texto em vez do arquivo. Se já tem o teor — passou o próprio OCR, ou o documento nasceu digital do seu lado —, use teor no lugar de arquivoId e pule os passos 3, 4 e 5 inteiros.

POST /integracao/ia/v1/analises
{
  "arquivoId": "<o id devolvido no passo 5>",
  "especieAto": "registro_integral",
  "naturezaCodigo": "LOCACAO_PREDIO"
}

→ 202 { "id": "...", "situacao": "na_fila" | "aguardando_ocr",
        "origemDoTeor": "arquivo", "especieAto": "registro_integral",
        "uf": "MG", "criadoEm": "..." }

Vários documentos na mesma análise

arquivoId aceita UM id (string) ou uma LISTA de ids (array). Com a lista, TODOS entram juntos na mesma análise — o primeiro é o documento principal e os demais são complementares, exatamente como o exame do balcão trata o título e seus anexos. Útil quando o ato se prova em mais de um arquivo (contrato + aditivo, ata + lista de presença).

POST /integracao/ia/v1/analises
{
  "arquivoId": ["<id do principal>", "<id do anexo>"],
  "especieAto": "registro_integral",
  "naturezaCodigo": "LOCACAO_PREDIO"
}

Ou, se você já tem o texto

POST /integracao/ia/v1/analises
{
  "teor": "ATA DA ASSEMBLEIA GERAL EXTRAORDINÁRIA DO CONDOMÍNIO…",
  "nomeDoDocumento": "ata-do-meu-sistema.pdf",
  "especieAto": "registro_integral",
  "naturezaCodigo": "ATA_CONDOMINIO"
}

→ 202 { "id": "...", "situacao": "na_fila", "origemDoTeor": "informado",
        "arquivoId": null, ... }
O que muda quando o teor é seu

É alternativa a arquivoId, não complemento: mandar os dois é recusado com 400 — com os dois não haveria como saber sobre qual dos textos o parecer foi feito.

E a resposta marca origemDoTeor: "informado" de propósito. Com arquivo, o que se examina é o documento; com teor, é o que você afirmou que o documento diz. É a mesma análise e não é a mesma cadeia de responsabilidade — e quem ler o parecer depois precisa poder saber disso sem ir perguntar.

A cobrança é por página, e sem arquivo não há página para contar: ela é estimada pelo tamanho do texto.

CampoObrigatórioO que é
arquivoIdum
ou
outro
o arquivo que você confirmou no passo 5. Pode ser pedido antes de a leitura terminar — a análise espera sozinha
teorum
ou
outro
o texto já extraído do seu lado, no lugar do arquivo. Mandar os dois é recusado
nomeDoDocumentonão como a análise se chama na lista do cartório quando não há arquivo com nome
especieAtosima espécie do ato pretendido — lista abaixo
naturezaCodigonão sem ele vale a lista geral do estado, e a resposta diz isso
uf— não mande. Vem da serventia do token; mandá-la é recusado, não ignorado

Espécies aceitas: registro_integral · registro_extrato · averbacao · anotacao · cancelamento · notificacao · arquivamento · matricula_rcpj · registro_pj · certidao · busca_apreensao

Por que 202, e não 200

O pedido foi aceito, não concluído. A leitura roda em segundo plano. Guarde o id e consulte por ele, ou espere o webhook.

Repetir é seguro. Enquanto o mesmo arquivo estiver aguardando_ocr, na_fila ou analisando, o pedido repetido devolve a MESMA análise, com o mesmo id e sem custo novo.

aguardando_ocr — a situação que você vai ver, e não é erro

Significa que o arquivo ainda está sendo transcrito. A análise entra na fila sozinha quando o texto ficar pronto; não é preciso pedir de novo nem esperar antes de pedir.

Se a leitura não terminar em 15 minutos, a análise falha com o motivo e nada é cobrado.

Quando a resposta não é 202

CódigoO que aconteceuO que fazer
400espécie ou natureza que o catálogo não conhece, ou uf no corpo a mensagem diz qual campo e para onde ir; não repita sem corrigir
401token vencido, inválido, ou autorização revogada troque uma asserção nova por outro token
403o teto diário de gasto daquela serventia acabou não é velocidade: reabre à meia-noite, e só o cartório altera o teto. Não implemente recuo exponencial para isto
404o documento não existe para esta serventia confira se o arquivo foi confirmado
409a serventia ainda não tem UF configurada tem conserto do nosso lado: avise o cartório

5 · Receber o resultado

Há dois caminhos, e eles não se excluem. O webhook é opcional; a consulta funciona sempre, e é o que sustenta quem está atrás de um firewall sem endereço público.

a) Consulta por id

GET /integracao/ia/v1/analises/{id}

→ 200 { "id": "...", "situacao": "na_fila" | "analisando" | "pronta" | "falhou",
        "resultado": { ... }   // só quando "pronta" }

Enquanto for na_fila ou analisando, não é erro — é o estado normal de quem ainda está lendo. Quando for pronta, vem junto a ficha extraída, os achados e o checklist respondido.

b) Reconciliação — o que mudou desde a última leitura

GET /integracao/ia/v1/analises?desde=2026-09-28T13:00:00.000Z

→ 200 { "analises": [...], "atualizadoAte": "...", "temMais": false }

É a rota de quem ficou fora do ar e precisa recuperar o que perdeu, sem consultar uma por uma. Guarde atualizadoAte e mande de volta como desde na próxima. A paginação é por tempo, e não por página: item que termina entre uma página e outra escapa de paginação por posição, e some sem ninguém notar.

c) Webhook, se o cartório cadastrou um

POST <a URL que o cartório cadastrou>
x-rtdpj-signature: t=<época>,v1=<hmac-sha256>
x-rtdpj-delivery: <id da entrega>

{ "evento": "analise.concluida", "id": "...", "situacao": "pronta",
  "analiseId": "...", "especieAto": "...", "naturezaCodigo": "...", "terminadoEm": "..." }

Como validar a assinatura (x-rtdpj-signature)

O header vem no formato t=<época>,v1=<hmac>. O v1 é um HMAC-SHA256 em hexadecimal sobre a string <t>.<corpo>, em que <t> é a época do próprio header e <corpo> é o corpo cru da requisição. O segredo é o whsec_… que apareceu uma única vez quando o cartório autorizou (ou trocou) o webhook — se o perder, gera-se outro.

  1. Leia x-rtdpj-signature e separe t e v1.
  2. Pegue o corpo CRU da requisição — antes de qualquer parse ou re-serialização.
  3. Monte base = t + "." + corpoCru.
  4. Calcule esperado = HMAC-SHA256(segredo, base) em hexadecimal.
  5. Compare esperado com v1 em tempo constante.
O erro número 1

Parsear o JSON e re-serializar para calcular o HMAC. A string muda (espaços, ordem das chaves) e a assinatura nunca bate. Use o corpo exatamente como chegou na rede. Recomenda-se ainda rejeitar avisos com t muito antigo — por exemplo, tolerância de 5 minutos — contra reenvio malicioso.

// Node
const crypto = require('crypto');
function validaWebhook(rawBody, headerSig, segredo) {
  const p = Object.fromEntries(headerSig.split(',').map(x => x.split('=')));
  const base = p.t + '.' + rawBody;                 // rawBody = corpo CRU (a string recebida)
  const esperado = crypto.createHmac('sha256', segredo).update(base).digest('hex');
  const bate = esperado.length === p.v1.length
    && crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(p.v1));
  const fresco = Math.abs(Date.now() / 1000 - Number(p.t)) <= 300;  // anti-replay
  return bate && fresco;
}
# Python
import hmac, hashlib, time
def valida_webhook(raw_body: bytes, header_sig: str, segredo: str) -> bool:
    p = dict(kv.split('=', 1) for kv in header_sig.split(','))
    base = (p['t'] + '.').encode() + raw_body        # raw_body = corpo CRU (os bytes recebidos)
    esperado = hmac.new(segredo.encode(), base, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, p['v1']) and abs(time.time() - int(p['t'])) <= 300

Delphi: THashSHA2.GetHMAC(t + '.' + corpoCru, segredo, SHA256) e compare o hex devolvido com o v1 — sempre com o corpoCru, não com o JSON re-serializado.

Recomendação

Mesmo com webhook, mantenha a reconciliação rodando de tempos em tempos. Entrega perdida acontece — rede, manutenção, certificado vencido do seu lado — e a análise já foi paga. Quem só escuta o aviso perde exatamente aquilo que mais custou.

6 · Limites e comportamento

AssuntoComo é
Validade do token10 minutos; renove trocando uma asserção nova
Tamanho do arquivoo teto vem na resposta do preparo (tetoBytes)
Escopo do tokenanalise:ler — não alcança registro, selo nem livro
Teto de gastodiário, por serventia; definido pelo cartório, reabre à meia-noite
Créditodo cartório, não seu; separado no momento do pedido
Isolamentovocê lê apenas as análises que a SUA credencial pediu, naquela serventia

7 · Para começar agora

Os dois caminhos do começo desta página continuam valendo, e nenhum depende do outro. Escolha pelo que você quer fazer primeiro — entender ou executar.

Entender
Swagger · referência das rotas

Os campos de cada entrada e de cada resposta, e o botão para disparar uma chamada ali mesmo. O openapi.json é a mesma coisa em arquivo, para gerar o cliente na sua linguagem.

Cada ambiente tem o seu — os links estão na
tabela de ambientes.
Executar
Postman · coleção pronta

As sete chamadas na ordem, com exemplos reais. Importe junto o environment do ambiente em que vai trabalhar, e não edite o endereço dentro da coleção.

O environment de cada ambiente também sai da
tabela de ambientes.