API de consulta de CNPJ
Os mesmos dados da consulta de CNPJ da Nume, por REST: 70,9 milhões de estabelecimentos da base pública da Receita Federal, com sócios, Simples e MEI, inscrições estaduais, dívida ativa, sanções e o histórico de alterações. Uma chave por conta, créditos por chamada, um plano grátis para testar.
Autenticação
Crie a chave em Conta → API de CNPJ. Ela aparece uma única vez, no
formato nume_live_…, e viaja no cabeçalho
Authorization: Bearer. Guarde-a no servidor,
nunca no navegador: quem tem a chave gasta os seus créditos. Revogue e crie outra a qualquer momento.
Endpoints
| Chamada | Créditos | O que devolve |
|---|---|---|
GET /v1/empresas/{cnpj} | 1 | Empresa (razão social, natureza jurídica, porte, capital, Simples/MEI) e o estabelecimento do CNPJ consultado: situação cadastral, CNAEs, endereço, telefones, e-mail, inscrições estaduais. |
GET /v1/empresas/{cnpj}?completo=1 | 2 | Tudo acima mais todos os estabelecimentos (matriz e filiais), o quadro de sócios, dívida ativa da União (PGFN), sanções (CGU) e o histórico de alterações campo a campo. |
GET /v1/empresas?uf=&municipio=&cnae=&situacao=… | 5 | Uma página (até 50) de empresas por filtros: uf, município, CNAE, situação, porte, Simples, MEI, com_email, com_telefone, matriz, bairro, CEP, razão social, capital, data de abertura, natureza jurídica. nome= busca por prefixo da razão social ou nome fantasia. Pelo menos um filtro. Planos pagos. |
GET /v1/socios?nome= | 2 | As empresas de um sócio, pelo prefixo do nome; filtros cnae e municipio. Planos pagos. |
GET /v1/empresas/{cnpj}/grupo | 5 | Grupo econômico: empresas que dividem sócio com esta. Aceita a raiz de 8 dígitos. Planos pagos. |
POST /v1/empresas/lote | 1 por encontrado | Até 100 CNPJs em uma chamada ({ "cnpjs": [...], "completo": false }); cobra só os encontrados, 2 cada com completo. Planos pagos. |
PUT /v1/webhook | 0 | Registra a URL https que recebe os avisos de alteração ({ "url": "https://…" }). GET mostra URL, secret e as últimas entregas; DELETE desativa. POST /v1/webhook/teste envia um evento de teste agora. Pro e Business. |
POST /v1/monitoramentos | 0 | Acompanha até 100 CNPJs por chamada ({ "cnpjs": [...] }), 1.000 no Pro e 10.000 no Business. GET lista; DELETE /v1/monitoramentos/{cnpj} tira um. |
evento empresa.alterada | 1 por aviso entregue | O POST que a Nume faz na sua URL quando um CNPJ acompanhado muda. Veja Webhooks de alteração. |
GET /v1 | 0 | Índice da API: endpoints, planos e créditos, em JSON. A descrição OpenAPI 3 está em /v1/openapi.json. |
Só respostas 200 consomem créditos, uma página vazia incluída. As páginas são fatias: pagina a partir de 0 e tem_proxima no lugar de um total. Inscrição estadual ao vivo e contatos atualizados chegam depois, com os créditos já publicados no índice.
Exemplo de resposta
{
"cnpj": "00000000000191",
"cnpj_basico": "00000000",
"razao_social": "BANCO DO BRASIL SA",
"natureza_juridica": { "codigo": "2038", "descricao": "Sociedade de Economia Mista" },
"porte": "DEMAIS",
"capital_social": 120000000000,
"simples": { "optante": false, "desde": null, "excluido_em": null },
"mei": { "optante": false, "desde": null, "excluido_em": null },
"estabelecimento": {
"cnpj": "00000000000191",
"matriz": true,
"nome_fantasia": "DIRECAO GERAL",
"situacao_cadastral": "ATIVA",
"data_situacao": "2005-11-03",
"data_abertura": "1966-08-01",
"cnae_principal": { "codigo": "6422100", "descricao": "Bancos múltiplos, com carteira comercial" },
"cnaes_secundarios": [ … ],
"endereco": { "logradouro": "SAUN QUADRA 5 LOTE B TORRE I", "bairro": "ASA NORTE", "cep": "70040912", "municipio": { "codigo": "9701", "descricao": "BRASILIA" }, "uf": "DF" },
"telefones": [ "6134939002" ],
"email": "…",
"inscricoes_estaduais": [ { "uf": "DF", "inscricao": "…" } ]
},
"total_estabelecimentos": 4123,
"atualizado_em": "2026-09-14T03:12:00",
"fonte": "Receita Federal do Brasil, base pública, atualização mensal"
} Datas em ISO 8601, valores em reais como número, códigos e descrições juntos em cada referência (CNAE, município, natureza jurídica, qualificação). CPFs de sócios vêm mascarados como na fonte.
Exemplos
curl
curl -H "Authorization: Bearer nume_live_SUA_CHAVE" \
"https://api.nume.solutions/v1/empresas/00000000000191?completo=1" curl: busca por filtros e lote
curl -H "Authorization: Bearer nume_live_SUA_CHAVE" \
"https://api.nume.solutions/v1/empresas?uf=PR&cnae=6920601&situacao=ATIVA&com_email=true&pagina=0"
curl -H "Authorization: Bearer nume_live_SUA_CHAVE" -H "Content-Type: application/json" \
-d '{"cnpjs":["00000000000191","33000167000101"],"completo":false}' \
https://api.nume.solutions/v1/empresas/lote Node.js
const r = await fetch('https://api.nume.solutions/v1/empresas/00000000000191', {
headers: { Authorization: 'Bearer ' + process.env.NUME_API_KEY },
});
if (r.status === 200) {
const empresa = await r.json();
console.log(empresa.razao_social, empresa.estabelecimento.situacao_cadastral);
} else {
const { error, message } = await r.json(); // invalid_key, rate_limited, credits_exhausted, not_found…
} Python
import os, requests
r = requests.get(
"https://api.nume.solutions/v1/empresas/00000000000191",
headers={"Authorization": f"Bearer {os.environ['NUME_API_KEY']}"},
params={"completo": 1},
)
if r.status_code == 200:
empresa = r.json()
print(empresa["razao_social"], len(empresa["socios"]), "sócios") Webhooks de alteração
Planos Pro e Business. Registre uma URL https, diga quais CNPJs quer acompanhar e a Nume avisa quando um deles muda: situação cadastral, endereço, sócios, capital, CNAE, dívida ativa, sanções. Cada aviso entregue custa 1 crédito. Um aviso que a sua URL não aceitou não custa nada.
PUT /v1/webhookcom{ "url": "https://seu.sistema/nume" }. A resposta traz osecretda assinatura. Guarde-o no servidor.POST /v1/monitoramentoscom{ "cnpjs": [...] }, até 100 por chamada.- A base é varrida uma vez por dia. A primeira passagem só marca o ponto de partida de cada CNPJ. Daí em diante, cada alteração nova vira um POST na sua URL com o evento
empresa.alterada, o cabeçalhoX-Nume-Signaturee umidque se repete em toda tentativa, para você deduplicar. - Responda 2xx em até 8 segundos. Sem 2xx, a Nume tenta de novo nas duas passagens seguintes. Na terceira falha o aviso fica como
failedemGET /v1/webhook, com o payload inteiro, e o crédito volta. POST /v1/webhook/testedispara um eventotestena hora, assinado do mesmo jeito.
O que chega
POST https://seu.sistema/nume
Content-Type: application/json
X-Nume-Event: empresa.alterada
X-Nume-Delivery: 7b1e4c2a-5d7f-4f7e-9c2b-0a1d2e3f4a5b
X-Nume-Signature: sha256=3f1a…
{
"id": "7b1e4c2a-5d7f-4f7e-9c2b-0a1d2e3f4a5b",
"evento": "empresa.alterada",
"enviado_em": "2026-10-05T12:00:03.000Z",
"cnpj": "00000000000191",
"razao_social": "BANCO DO BRASIL SA",
"observado_em": "2026-10-04T03:10:00",
"alteracoes": [
{ "entidade": "Estabelecimento", "campo": "situacaoCadastral", "de": "ATIVA", "para": "SUSPENSA", "observado_em": "2026-10-04T03:10:00" }
]
} Conferindo a assinatura (Node)
A assinatura cobre os bytes exatos do corpo. Confira antes de fazer o parse, e compare em tempo constante.
import { createHmac, timingSafeEqual } from 'node:crypto';
app.post('/nume', express.raw({ type: 'application/json' }), (req, res) => {
const expected = 'sha256=' + createHmac('sha256', process.env.NUME_WEBHOOK_SECRET).update(req.body).digest('hex');
const given = req.get('X-Nume-Signature') ?? '';
if (given.length !== expected.length || !timingSafeEqual(Buffer.from(given), Buffer.from(expected))) return res.status(401).end();
const evento = JSON.parse(req.body); // evento.id para deduplicar; evento.cnpj; evento.alteracoes
res.status(200).end(); // responda antes de processar: 8 segundos é o limite
}); Planos e créditos
| Plano | Por mês | Créditos/mês | Req./minuto | Inclui |
|---|---|---|---|---|
| Dev | Grátis | 100 (20 por dia) | 3 | Para testar a integração. 100 créditos por mês, 20 por dia, 3 requisições por minuto. |
| Starter | R$ 49,90 | 10.000 | 30 | 10 mil créditos por mês, 30 requisições por minuto, todos os endpoints. |
| Pro | R$ 149,90 | 50.000 | 120 | 50 mil créditos por mês, 120 requisições por minuto, lote e webhooks em mil CNPJs. |
| Business | R$ 499,90 | 250.000 | 300 | 250 mil créditos por mês, 300 requisições por minuto, webhooks em 10 mil CNPJs, lista de IPs, suporte prioritário. |
O plano Dev existe para testar a integração, não para operar: 100 créditos por mês, 20 por dia.
Nos planos pagos, quando os créditos do mês acabam, cada R$ 1 do
saldo da conta compra 100 créditos extras, automaticamente.
Sem saldo, a API responde 402 e para. Nunca há cobrança depois do fato, nem fatura surpresa.
Limites e erros
Cada resposta traz X-RateLimit-Limit, X-Credits-Remaining,
X-Credits-Overage e X-Credits-Charged. Erros vêm como
{ "error": "...", "message": "..." }:
| HTTP | error | Quando |
|---|---|---|
| 400 | invalid_cnpj | O CNPJ não tem 14 dígitos válidos. |
| 400 | missing_filter | Busca sem nenhum filtro e sem nome=. |
| 401 | invalid_key | Chave ausente, mal formada ou revogada. |
| 403 | plan_required | Busca, sócios, grupo e lote pedem um plano pago; webhooks e monitoramentos, Pro ou Business. |
| 400 | invalid_url | A URL do webhook não é https em um host público. |
| 404 | no_webhook | Teste de webhook sem um webhook ativo. |
| 403 | ip_not_allowed | O endereço de origem não está na lista de IPs da chave. |
| 402 | credits_exhausted | Créditos do mês e saldo da conta esgotados. Nada é cobrado depois. |
| 404 | not_found | CNPJ não existe na base. Não é cobrado. |
| 429 | rate_limited | Acima das requisições por minuto do plano. Veja Retry-After. |
| 429 | daily_cap | Plano Dev: acima dos créditos do dia. |
| 503 | backend_unavailable | A base está fora do ar. Não é cobrado; tente em alguns minutos. |
Referência completa
Gerada da mesma descrição OpenAPI que a API publica em /v1/openapi.json: cada chamada com os seus parâmetros, o corpo que aceita e as respostas que dá. Importe o arquivo no Postman, no Insomnia ou em um gerador de cliente.
GET/v1
Índice: endpoints, planos e créditos
200: OK · 404: Qualquer outro caminho fora de /v1 (not_found)
GET/v1/empresas/{cnpj}
Uma empresa pelo CNPJ (1 crédito; 2 com completo=1)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
cnpj * | caminho | string | 14 dígitos, com ou sem pontuação |
completo | query | 0 | 1 | completo=1 inclui todos os estabelecimentos, sócios, dívida ativa, sanções e histórico |
200: A empresa · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 402: Créditos do mês e saldo esgotados (credits_exhausted). Nada é cobrado depois. · 403: Plano sem o endpoint (plan_required) ou IP fora da lista da chave (ip_not_allowed) · 404: CNPJ fora da base (not_found). Não é cobrado. · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
GET/v1/empresas
Busca por filtros ou por nome (5 créditos por página; planos pagos)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
nome | query | string | Prefixo da razão social ou nome fantasia (3 letras ou mais). Com nome=, os outros filtros são ignorados |
uf | query | string | UF, duas letras |
municipio | query | string | Código IBGE/Receita do município |
cnae | query | string | CNAE principal, 7 dígitos |
situacao | query | string | ATIVA, BAIXADA, INAPTA, SUSPENSA, NULA |
porte | query | string | ME, EPP, DEMAIS |
simples | query | string | true/false |
mei | query | string | true/false |
com_email | query | string | true/false |
com_telefone | query | string | true/false |
matriz | query | string | true/false |
bairro | query | string | |
cep | query | string | 8 dígitos |
razao | query | string | Prefixo da razão social |
cnpj_basico | query | string | Raiz do CNPJ, 8 dígitos |
capital_min | query | string | Capital social mínimo, em reais |
capital_max | query | string | Capital social máximo, em reais |
abertura_min | query | string | Data de abertura a partir de (AAAA-MM-DD) |
abertura_max | query | string | Data de abertura até (AAAA-MM-DD) |
natureza_juridica | query | string | Código da natureza jurídica |
ente_federativo | query | string | |
pagina | query | integer | Página, a partir de 0 |
por_pagina | query | integer | Até 50 |
200: Uma página de empresas · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 402: Créditos do mês e saldo esgotados (credits_exhausted). Nada é cobrado depois. · 403: Plano sem o endpoint (plan_required) ou IP fora da lista da chave (ip_not_allowed) · 404: CNPJ fora da base (not_found). Não é cobrado. · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
POST/v1/empresas/lote
Até 100 CNPJs por chamada (1 crédito por CNPJ encontrado, 2 com completo; planos pagos)
Corpo (JSON): cnpjs *: lista de string · completo: boolean
200: Um resultado por CNPJ enviado, na ordem · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 402: Créditos do mês e saldo esgotados (credits_exhausted). Nada é cobrado depois. · 403: Plano sem o endpoint (plan_required) ou IP fora da lista da chave (ip_not_allowed) · 404: CNPJ fora da base (not_found). Não é cobrado. · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
GET/v1/empresas/{cnpj}/grupo
Grupo econômico: empresas com sócio em comum (5 créditos por página; planos pagos)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
cnpj * | caminho | string | CNPJ de 14 dígitos ou a raiz de 8 |
pagina | query | integer | Página, a partir de 0 |
200: Uma página de empresas · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 402: Créditos do mês e saldo esgotados (credits_exhausted). Nada é cobrado depois. · 403: Plano sem o endpoint (plan_required) ou IP fora da lista da chave (ip_not_allowed) · 404: CNPJ fora da base (not_found). Não é cobrado. · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
GET/v1/socios
Empresas de um sócio, por prefixo do nome (2 créditos por página; planos pagos)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
nome * | query | string | |
cnae | query | string | CNAE principal, 7 dígitos |
municipio | query | string | Código do município |
pagina | query | integer | Página, a partir de 0 |
200: Uma página de empresas · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 402: Créditos do mês e saldo esgotados (credits_exhausted). Nada é cobrado depois. · 403: Plano sem o endpoint (plan_required) ou IP fora da lista da chave (ip_not_allowed) · 404: CNPJ fora da base (not_found). Não é cobrado. · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
GET/v1/webhook
O webhook da conta: URL, secret e as últimas 20 entregas (0 créditos; Pro e Business)
200: O webhook, ou { url: null, ativo: false } se nenhum foi registrado · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
PUT/v1/webhook
Registra ou troca a URL https que recebe os avisos; o secret é mantido (0 créditos; Pro e Business)
Corpo (JSON): url *: string (ex.: https://seu.sistema/nume)
Chamada de volta na sua URL: Um CNPJ monitorado mudou (1 crédito por aviso entregue). Até 3 tentativas, uma por passagem diária
200: O webhook, com o secret · 400: URL recusada (invalid_url: só https, host público, sem usuário e senha) ou JSON inválido (bad_request) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
DELETE/v1/webhook
Desativa o webhook; URL, secret e monitoramentos ficam (0 créditos; Pro e Business)
200: { ativo: false, desativado: true|false } · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
POST/v1/webhook/teste
Envia um evento teste à URL registrada agora, assinado como os reais (0 créditos; Pro e Business)
200: { id, entregue: true|false, status_http } · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 404: Nenhum webhook ativo (no_webhook) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
GET/v1/monitoramentos
Os CNPJs que a conta acompanha, 100 por página, e o limite do plano (0 créditos; Pro e Business)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
pagina | query | integer | Página, a partir de 0 |
200: Uma página de monitoramentos · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
POST/v1/monitoramentos
Acompanha até 100 CNPJs a mais por chamada, dentro do limite do plano (1000 no Pro, 10000 no Business) (0 créditos)
Corpo (JSON): cnpjs *: lista de string
200: Quantos entraram, já estavam, foram recusados pelo limite ou eram inválidos · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
DELETE/v1/monitoramentos/{cnpj}
Deixa de acompanhar um CNPJ (0 créditos; Pro e Business)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
cnpj * | caminho | string | 14 dígitos, com ou sem pontuação |
200: { cnpj, removido: true } · 400: Pedido inválido (invalid_cnpj, missing_filter, invalid_nome, bad_request, too_many) · 401: Chave ausente, mal formada ou revogada (invalid_key) · 403: Plano sem webhooks (plan_required: Pro ou Business) ou IP fora da lista da chave (ip_not_allowed) · 404: Este CNPJ não estava monitorado (not_found) · 429: Acima das requisições por minuto (rate_limited) ou do dia no plano Dev (daily_cap). Veja Retry-After. · 503: Base indisponível (backend_unavailable, service_unavailable). Não é cobrado.
Planos, preços e o botão de assinar estão em /servicos/api-cnpj.
Os dados
A fonte é a base pública do CNPJ da Receita Federal do Brasil, carregada a cada publicação mensal, mais as bases abertas de dívida
ativa (PGFN) e de sanções (CGU). A API devolve o que a fonte publica: nomes de sócios com CPF mascarado, contatos cadastrais da
empresa, nada além. Não há promessa de tempo real: o campo atualizado_em diz de quando é cada registro.
Guarde em cache o que não muda todo dia e consulte de novo quando precisar.