documentação pública
Consultas, monitoramento e webhooks: a referência da API.
Tudo o que a API publica hoje — processos, publicações do diário, jurisprudência, monitores e webhooks — com contratos, custos e exemplos. Se você decide e não integra, comece pelas três perguntas logo abaixo.
Sua primeira resposta em 60 segundos
Crie uma chave no portal, cole a chave no lugar de lapi_live_sua_chave e rode os três comandos na ordem. Nenhum deles consome crédito: descobrir que a integração funciona não gasta franquia.
Passo 1
Prove a chave
curl -H "Authorization: Bearer lapi_live_sua_chave" \ https://api.lexnode.com.br/v1/usageResponde na hora, do próprio motor, e devolve o consumo do período com o saldo restante. Se voltar 200, a credencial está válida e o resto da travessia funciona.
Passo 2
Ponha o motor a vigiar
curl -X POST "https://api.lexnode.com.br/v1/monitors" \ -H "Authorization: Bearer lapi_live_sua_chave" \ -H "Content-Type: application/json" \ -d '{"type":"OAB","oabNumber":"123456","oabState":"SP"}'Cadastra a inscrição na OAB e encerra a consulta periódica: a varredura dos diários passa a acontecer no servidor, todo dia, com o seu programa desligado.
Passo 3
Colha o que chegou
curl -H "Authorization: Bearer lapi_live_sua_chave" \ "https://api.lexnode.com.br/v1/events?limit=50"Devolve o acumulado desde a sua última leitura e avança o marcador. É a mesma resposta que o webhook entrega — quem prefere receber cadastra um endpoint e não chama mais nada.
Prefere clicar a digitar?
Importe a coleção no Postman, no Insomnia ou no Bruno: as mesmas chamadas, mais as de processo, diário, jurisprudência e webhooks, já com a autenticação configurada e o custo de cada uma na descrição.
Para quem decide, antes da parte técnica
Recebo as publicações da minha OAB automaticamente?
Sim. Um monitor de OAB varre o diário oficial e cada publicação nova chega ao seu sistema por webhook — ninguém precisa ficar consultando.
Quanto custa cada consulta?
Cada operação tem custo fixo em créditos, listado na tabela desta página — e toda resposta da API confirma o valor cobrado. Os planos estão em /precos.
O sistema que meu escritório já usa consegue conectar?
Qualquer sistema que fale HTTP consegue. Quem integra é o fornecedor do seu software (ou o seu dev), usando esta referência; o escritório só colhe o resultado.
Receber as publicações de uma OAB em quatro passos
É o caminho mais usado, e o que mais economiza chamadas: você cadastra a OAB uma vez e o motor avisa quando sai publicação. Não é preciso consultar de tempos em tempos para descobrir novidade — a novidade é que chega até você.
Passo 1
Cadastre o endereço que recebe
POST /v1/webhooks/endpoints
A URL do seu sistema (ou do seu fluxo de automação) e os eventos que ela aceita. Comece por PUBLICATION_CREATED. Guarde o segredo devolvido: é com ele que a assinatura de cada entrega é conferida.
Passo 2
Cadastre a OAB a acompanhar
POST /v1/monitors { "type": "OAB", "oabNumber": "123456", "oabState": "SP" }
A varredura passa a rodar sozinha, uma vez por edição do diário. Não custa crédito, e é ela que substitui a consulta em laço.
Passo 3
Receba o aviso
PUBLICATION_CREATED → seu endpoint
Chega processo, tribunal, data e um trecho do teor. Já dá para triar sem nenhuma chamada de volta.
Passo 4
Leia o ato quando precisar do teor
GET /v1/publications/{publicationKey}?maxTextChars=4000
Custa 0 créditos. Use maxTextChars para não receber uma pauta inteira quando bastava o começo do ato, e guarde o ETag: relendo com If-None-Match, a resposta volta sem corpo.
Usa n8n, Make ou outra ferramenta de automação? Os quatro passos são requisições HTTP comuns — nenhum passo exige escrever código. O nó que recebe o webhook é o passo 3, e a conferência da assinatura está descrita em webhooks.
Pesquisar jurisprudência em quatro chamadas
A pesquisa de acórdãos vive sob /v1/publications e trabalha com resultado congelado: a busca vira um recurso permanente, e reabri-la depois não custa crédito nem muda o resultado.
Passo 1
Confira a cobertura
GET /v1/publications/corpus/coverage
Diz se o tribunal, o período e a matéria que você quer já estão indexados — e quais matérias ficam fora do acervo. Custa 0 créditos e é o que separa “não existe julgado” de “ainda não está no acervo”.
Passo 2
Pesquise e congele
POST /v1/publications/text-searches
Devolve os acórdãos ranqueados com relator, órgão julgador, data de julgamento e classe, quando a decisão os informa — e grava o resultado como um recurso permanente, com id próprio.
Passo 3
Leia o teor
GET /v1/publications/text-searches/{searchId}
Traz o teor de cada acerto e não custa crédito. A mesma busca reaberta amanhã devolve o mesmo resultado — é o que torna a citação reproduzível numa peça. Para receber o teor já no passo 2, mande hydrate: true: é esta mesma leitura, na mesma chamada e sem crédito extra.
Passo 4
Acompanhe o tema
POST /v1/publications/text-alerts
Transforma a pesquisa em vigília permanente: quando aparecem julgados novos que casam com a consulta, o seu endpoint recebe um aviso PUBLICATION_TEXT_ALERT_MATCHED, com uma prévia deles e o total.
Pelo pacote TypeScript
A pesquisa só de decisões colegiadas, a citação de cada acerto e a reabertura da mesma busca, sem custo, pela chamada genérica do pacote.
import { createLexNodeClient } from "@lexnode/legal-data-sdk";
const lexnode = createLexNodeClient({
baseUrl: "https://api.lexnode.com.br",
apiKey: process.env.LEXNODE_API_KEY!,
});
const { data } = await lexnode.publications.textSearch({
query: "dano moral inscrição indevida cadastro de inadimplentes",
collegiateOnly: true,
limit: 10,
});
for (const item of data.items) {
console.log(item.position, item.judgmentClass, item.rapporteur);
console.log(item.courtBody, item.judgedAt, item.headline);
}
// Reabrir depois: a mesma lista, na mesma ordem, sem custo.
const reaberta = await lexnode.request(
"/v1/publications/text-searches/{searchId}",
"get",
{
params: {
path: { searchId: data.searchId },
query: { page: 2, pageSize: 10 },
},
},
);O mesmo pelo assistente de IA, sem código: Como pesquisar jurisprudência no Claude e ChatGPT. Uma explicação sem jargão, com o que exigir de qualquer fornecedor: API de jurisprudência: o que existe e como usar.
O que o acervo cobre, por matéria
Uma pesquisa vazia só é resposta quando se sabe se a matéria está no acervo. A lista abaixo é a declaração do motor — a mesma que a rota de cobertura devolve, ali com estado e contagem por tribunal.
No acervo
Justiça estadual
Cível, família e sucessões, consumidor, empresarial e criminal de competência estadual: publicações do diário oficial dos tribunais de justiça e o acervo estruturado de acórdãos do tribunal do Distrito Federal.
Justiça federal
Previdenciário, tributário e administrativo em juízo federal: publicações do diário oficial dos tribunais regionais federais.
Direito federal infraconstitucional
Uniformização da lei federal pelo tribunal superior: espelho estruturado dos acórdãos, inteiros teores e publicações do diário oficial. Os precedentes qualificados têm rota própria.
Trabalhista
Publicações do diário oficial dos tribunais regionais do trabalho e do tribunal superior do trabalho: sentença, acórdão e despacho como publicados, não um acervo indexado por ementa.
Militar
Publicações do diário oficial do tribunal superior militar e das justiças militares estaduais.
Tributário administrativo
Acórdãos do contencioso administrativo fiscal federal, com ementa, decisão e inteiro teor.
Fora do acervo
Eleitoral
Jurisprudência dos tribunais regionais eleitorais e do tribunal superior eleitoral.
Constitucional
Jurisprudência do tribunal constitucional: controle de constitucionalidade e recurso extraordinário.
Previdenciário administrativo
Decisões do contencioso administrativo previdenciário, antes do juízo federal.
Atos normativos do Judiciário
Resoluções, provimentos e recomendações do conselho nacional do Judiciário.
Controle externo de contas
Acórdãos do tribunal de contas federal.
Quando um total: 0 não quer dizer “não existe”
Uma busca vazia é ambígua por natureza: pode não haver o que procurar, ou pode ainda não ter chegado. A própria resposta resolve isso por você — toda busca que consulta a fonte volta com sourceIndex, e é ele que qualifica o zero. Lê-se junto com o resultado, sem chamada extra e sem crédito adicional.
Na busca de processos
sourceIndex.updatedThrough
A data até onde o índice da fonte está atualizado. Processo distribuído depois dela ainda não é encontrável: ali, total: 0 quer dizer “ainda não chegou”, não “não existe”. Antes de responder ao usuário que o processo não existe, compare essa data com a da distribuição — e, com o campo vazio, trate a resposta como indeterminada.
Na busca de publicações
sourceIndex.lastEditionDate
A última edição do diário detectada no ar. Sai uma por dia útil: sem a edição de hoje detectada, total: 0 quer dizer “ainda não saiu”, e o campo vazio deixa a resposta indeterminada. E a prova vale numa direção só — a edição de hoje no ar não garante o dia inteiro, então um zero de agora ainda pode virar publicação daqui a algumas horas.
Para o que sai hoje, reperguntar é o pior jeito de descobrir: o aviso do monitor chega sozinho, e o caminho está logo abaixo, em manter um processo atualizado.
Onde estão as partes e os advogados
Eles vêm pelo eixo do diário, e cada publicação os traz em campo próprio — não é preciso ler o texto para descobrir quem está no processo nem de que vara ele veio. O eixo do processo responde outra pergunta: o que andou. Mantenha os dois ligados e você tem as duas respostas.
parties
Quem a publicação nomeia
Nome e polo de cada parte intimada no ato, como a origem os declara. Vem pelo eixo do diário. Uma parte que não foi intimada naquele ato não aparece nele — é a publicação que traz a lista, não o cadastro do processo.
lawyers
Quem advoga
Nome do advogado com número e UF da inscrição, quando a origem os traz. Também pelo eixo do diário. É o campo que liga a publicação a um escritório sem casar texto.
courtBody
De que órgão veio
O órgão julgador, como a fonte o escreve. Chega nos dois eixos — é o único dos três que o acervo de jurisprudência também nomeia.
Dois campos que costumam ser pedidos junto não são servidos, e é melhor saber antes de desenhar em cima deles: o valor da causa e o nome do magistrado que assina. Quando aparecem, aparecem como texto corrido dentro do teor, por ato e sujeitos a substituição — não há campo para eles porque não há dado estruturado por trás. Publicação sob segredo de justiça sai sem partes e sem advogados, como já sai sem teor.
No eixo do processo, a mesma disciplina tem nome de campo: cada processo chega com confidentiality e shareable. É a classificação do motor sobre a linha, e não o marcador da origem, que quase sempre vem vazio. Se você exibe processo a um público, é por esses dois campos que a tela se fecha — antes do teor, e não depois de mostrá-lo.
Manter um processo atualizado
A busca é o caminho mais lento, e consultá-la em laço é o jeito mais caro de descobrir novidade. Os três caminhos abaixo não são etapas de uma sequência: mantenha o eixo do processo e o eixo do diário ligados ao mesmo tempo, e guarde a busca para quando precisar do estado agora.
ler agora
Puxe o estado atual
GET /v1/processes/{processNumber}
Devolve o processo como o motor o tem. Se o que ele tem já passou de 24 horas, ele relê a fonte antes de responder — e o plano pode encurtar esse prazo. É a chamada de quem precisa do estado agora; repetida em laço, ela só paga de novo por uma resposta que quase sempre é igual à anterior.
ser avisado
Deixe o motor conferir por você
POST /v1/monitors { "type": "PROCESS", ... }
O motor confere o processo sozinho e empurra a novidade ao seu endpoint. A conferência não custa crédito, por mais frequente que seja — é ela que substitui a consulta em laço.
ver quando o juízo falou
Vigie o diário
POST /v1/monitors { "type": "TERM", "term": "..." }
O ato publicado chega na edição do dia, direto ao seu endpoint, com processo, tribunal, data e um trecho do teor. É por aqui que a intimação aparece — e o mesmo endpoint aceita uma OAB, um nome de parte (type PARTY) ou um CNPJ (type DOCUMENT, partyDocument em qualquer grafia) no lugar do termo, sem exigir saber de antemão o número do processo. A vigília por CNPJ casa o documento no teor e por isso entrega a publicação que cita a empresa antes de ela ser parte — cada achado vem com matchedBy: "document". CPF não é aceito como alvo de vigília.
O eixo do processo e o eixo do diário não se substituem. Acompanhar um processo pede os dois em conjunto: o mesmo ato aparece nos dois eixos em momentos diferentes, e com um só ligado você fica sempre com o mais tardio dos dois.
entradas documentadas
Como a API recebe as consultas hoje
Os contratos abaixo refletem os filtros realmente definidos nos schemas públicos da API neste momento.
Créditos por operação
O plano dá um saldo mensal de créditos. O custo é fixo por operação e toda resposta confirma a cobrança em meta.credits.
Além do saldo, há dois tetos de chamadas, e eles contam coisas diferentes. O por minuto conta toda requisição. O por dia conta apenas as que precisam consultar a fonte — o que já está no acervo não gasta o teto diário. Ao estourar qualquer um deles a resposta é 429 RATE_LIMITED com Retry-After, e o campo details.window diz qual dos dois foi.
Não é preciso esperar a recusa para saber quanto resta: toda resposta traz RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset do teto por minuto. Eles descrevem só essa janela — o consumo do dia e do ciclo se consulta em GET /v1/usage, que não custa crédito e discrimina por operação e por cliente seu. Na resposta de sucesso o Reset é a janela inteira em segundos; quem for recusado recebe no 429 o instante exato em que ela reabre.
Os números de cada plano — vazão, franquia, monitores, teto por chave e os tetos por requisição — estão reunidos em limites e cotas.
| Operação | Créditos |
|---|---|
| Descoberta, saúde, tribunais, calendário forense | 0 |
| POST /v1/processes/search | 1 com dado fresco no lake · 3 consultando a fonte |
| GET /v1/processes/{processNumber} | 1 com dado fresco no lake · 3 consultando a fonte · 1 com a cópia guardada quando a fonte falha |
| GET /v1/processes/{processNumber}/related | 1 |
| GET /v1/processes/{processNumber}/movements | 5 |
| GET /v1/processes/{processNumber}/snapshot | 8 · 1 com a cópia guardada quando a fonte falha |
| POST /v1/processes/snapshot-batch | 8 por item concluído · 1 pelo item servido com a cópia guardada |
| POST /v1/processes/lookups | o preço da leitura direta quando ela cabe na espera · 0 enquanto segue em segundo plano, e só se o processo vier: 8 pelo retrato, 3 pela ficha, ou 1 pela ficha que outra leitura trouxe ao acervo nesse meio-tempo · 1 pela cópia guardada em stale, e a entrega cobra o resto |
| GET /v1/processes/lookups, a leitura e o cancelamento de uma consulta | 0 |
| GET /v1/publications por processo | 2 |
| GET /v1/publications por OAB | 5 |
| GET /v1/publications por janela de tribunal ou por texto | 8 |
| GET /v1/publications/{publicationKey} | 0 |
| POST /v1/publications/text-searches | 3 (+1 por fatia nova de colheita) |
| POST /v1/publications/corpus/harvest-requests | 1 por fatia nova |
| POST /v1/legal-norms/resolve | 3 · citação não entendida ou fora do alcance do registro: 0 |
| Vigílias de texto, monitores (processo, OAB, termo, nome de parte, CNPJ), assinaturas, jobs de busca, webhooks, uso | 0 |
Erros e comportamento
Todo erro chega no envelope { error: { code, message, requestId, class, retryable } }. Recurso de outra conta responde 404, nunca 403 — fora do seu escopo, o recurso não existe.
| code | HTTP | Vale reenviar? |
|---|---|---|
| VALIDATION_ERROR | 400 | não |
| PERSONAL_DOCUMENT_QUERY_NOT_ALLOWED | 400 | não |
| UNAUTHORIZED | 401 | não |
| QUOTA_EXCEEDED | 402 | não |
| INSUFFICIENT_SCOPE · LGPD_FORBIDDEN | 403 | não |
| PLAN_FEATURE_NOT_INCLUDED | 403 | não |
| SUB_TENANT_LIMIT_EXCEEDED | 403 | não |
| PROCESS_NOT_FOUND · MOVEMENTS_NOT_AVAILABLE · RESOURCE_NOT_FOUND | 404 | não |
| RESOURCE_CONFLICT | 409 | não |
| RATE_LIMITED | 429 | sim |
| UPSTREAM_RATE_LIMITED | 429 | sim |
| INTERNAL_ERROR | 500 | não |
| UPSTREAM_UNAVAILABLE | 502 | sim |
| SOURCE_MAINTENANCE | 503 | sim |
| UPSTREAM_TIMEOUT | 504 | sim |
O header opcional X-Request-Id é ecoado na resposta e serve ao rastreio em qualquer rota; na busca textual ele funciona também como chave de idempotência, e reenviar o mesmo valor reapresenta a busca já congelada sem nova cobrança. A busca assíncrona de processos deduplica pelo corpo, e não por ele: a mesma busca devolve o job que já existe, em aberto ou concluído há menos de 180 dias, sem nova cobrança, e abre outro depois de um job que falhou, foi cancelado ou passou desse prazo. Nas demais rotas ele não deduplica nada. X-Office-Id atribui a chamada a um sub-tenant seu na medição de uso — e recorta o que a leitura enxerga: com ele, monitores, jobs de busca e assinaturas alcançam o que foi atribuído àquele sub-tenant e o que não foi atribuído a nenhum; sem ele, a conta inteira. A fronteira entre contas é sempre a chave de API, nunca este header. Uma plataforma que atende vários clientes finais abre uma conta só e usa um valor por cliente; cada plano diz quantos sub-tenants admite por período — GET /v1/usage devolve o teto e quantos já foram atendidos, e um sub-tenant novo além dele responde 403 SUB_TENANT_LIMIT_EXCEEDED; os já atendidos passam sempre.
Monitores + webhooks: o acompanhamento sem polling
Os 12 tipos de evento chegam assinados (HMAC-SHA256) no endpoint do seu sistema, com política de reentrega documentada. O guia traz payloads de exemplo e o código de verificação da assinatura.
pacote typescript
O contrato inteiro, com o cliente pronto
O pacote @lexnode/legal-data-sdk traz requisições, respostas e erros de cada rota como tipos gerados do openapi.json — e um cliente de runtime sobre eles: chamadas tipadas com atribuição de sub-tenant, erros classificados, verificação de webhook, espera de busca assíncrona e vigília de processo. Sem dependências, só no servidor: a chave é de conta. Quem prefere o próprio transporte continua usando só os tipos. A versão do pacote acompanha a do contrato.
Instalação
npm install @lexnode/legal-data-sdkUso
import {
createLexNodeClient,
parseWebhookEvent,
} from "@lexnode/legal-data-sdk";
const lexnode = createLexNodeClient({
baseUrl: process.env.LEXNODE_API_BASE_URL!,
apiKey: process.env.LEXNODE_API_KEY!,
});
const { data, meta } = await lexnode.publications.list(
{ oabNumber: "123456", oabState: "SP" },
{ officeId: "escritorio-01" },
);
data.items.length;
meta.credits;
// No receptor do webhook, sobre os BYTES CRUS do corpo:
const entrega = parseWebhookEvent(rawBody, headers, signingSecret);Só os tipos
import type { paths, operations } from "@lexnode/legal-data-sdk";
// Uma operação inteira, pela rota e pelo método:
type SearchProcesses = paths["/v1/processes/search"]["post"];
// Ou pelo operationId — aqui, o corpo de sucesso de listTribunals:
type Tribunals =
operations["listTribunals"]["responses"][200]["content"]["application/json"]["data"];exemplos de integração
Snippets prontos para stacks comuns nesse tipo de operação
Selecione a linguagem e o endpoint publicado que você quer integrar. As rotas dinâmicas já entram comprocessNumbere os parâmetros obrigatórios no snippet.
referência viva da API
Endpoints públicos disponíveis agora
Esta lista é carregada a partir do openapi.json da API. A UI completa do Swagger continua disponível em paralelo para consulta direta.