CPFHub.io

Consulta de CNPJ em Lote

Envie uma lista de até 10.000 CNPJs e receba, para cada um, o mesmo registro da Consulta de CNPJ, processado em segundo plano. Custa 1 crédito por CNPJ encontrado.

Usando Cursor, Lovable, v0 ou outra IA? Copie o prompt da consulta de CNPJ em lote e cole no seu assistente.

Abrir no Cursor

Sem código, o dashboard aceita uma lista de CNPJs e mostra o resultado de cada um.

Fluxo em dois passos:

  1. POST /cnpj/bulk envia a lista e responde na hora com um jobId.
  2. GET /cnpj/bulk/{jobId} devolve o progresso e os resultados. Repita até status ser "done" ou "failed".

Endpoint

POSThttps://api.cpfhub.io/cnpj/bulk

Parâmetros

OndeNomeObrigatórioDescrição
Headerx-api-keySimSua API Key. Veja Autenticação.
HeaderContent-TypeSimapplication/json
BodycnpjsSimstring[] de CNPJs, com ou sem formatação, numéricos ou alfanuméricos. Não vazio, máximo 10.000. Itens que não são string contam como inválidos.
BodyfileNameNãoRótulo livre. Volta como file_name no status.
BodyformatNãoRótulo livre do formato de origem (ex.: "csv"). Volta como format.

O que acontece no envio

EtapaEfeito
NormalizaçãoRemove pontos, barra e traço e converte letras para maiúsculas. CNPJs com formato errado ou dígito verificador incorreto vão para invalid e não são cobrados.
DuplicadosRemovidos. Cada CNPJ é consultado e cobrado uma vez. Não entram em totalRecords nem em invalid.
SaldoSem overage: o saldo precisa cobrir todos os CNPJs válidos (totalRecords × custo da consulta, 1 crédito no padrão). Se não cobrir, 403 e nada é cobrado.
Lotes pendentesExiste um limite de lotes em processamento ao mesmo tempo por cliente. Acima dele, 429.

Mais de 10.000 CNPJs: divida em blocos e envie um POST para cada um, aguardando os anteriores se receber 429.

Exemplo

Confira o status antes de ler data: em erro, a resposta não traz jobId.

curl -X POST "https://api.cpfhub.io/cnpj/bulk" \
  -H "x-api-key: $CPFHUB_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "cnpjs": ["11222333000181", "12.ABC.345/01DE-35"]
  }'

Resposta

HTTP 202 Accepted

JSON
{
  "success": true,
  "data": {
    "jobId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "processing",
    "totalRecords": 2,
    "invalid": 0
  }
}
CampoTipoDescrição
data.jobIdstringID do lote. Guarde para consultar o status.
data.statusstringSempre "processing"
data.totalRecordsnumberCNPJs válidos e únicos que serão consultados
data.invalidnumberItens descartados (formato, dígito verificador ou não string)

O envio responde em camelCase. O status responde em snake_case.

Status e resultados

GEThttps://api.cpfhub.io/cnpj/bulk/{jobId}

Use a mesma API Key do envio. Não consome crédito e funciona com saldo zerado.

Polling:

  • Comece a cada 5 s e aumente até 30 s em lotes grandes. Cada chamada devolve o array cnpjs inteiro, e cada registro de CNPJ é bem maior que o de um CPF.
  • Defina um prazo máximo no cliente (ex.: 30 min). O tempo do lote depende de quantos CNPJs estão no envio.
  • Em 5xx ou erro de rede, tente de novo no próximo ciclo. O GET é seguro para repetir.
curl "https://api.cpfhub.io/cnpj/bulk/7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -H "x-api-key: $CPFHUB_API_KEY"

HTTP 200 OK

JSON
{
  "success": true,
  "data": {
    "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "done",
    "file_name": null,
    "format": null,
    "total_records": 2,
    "processed": 2,
    "found": 1,
    "not_found": 1,
    "skipped": 0,
    "error": null,
    "created_at": "2026-10-15T14:15:16.000Z",
    "updated_at": "2026-10-15T14:15:18.000Z",
    "cnpjs": [
      {
        "cnpj": "11222333000181",
        "found": true,
        "data": {
          "cnpj": "11222333000181",
          "razao_social": "EMPRESA EXEMPLO LTDA",
          "situacao_cadastral": "Ativa",
          "...": "demais campos da Consulta de CNPJ"
        }
      },
      {
        "cnpj": "12ABC34501DE35",
        "found": false,
        "data": null
      }
    ]
  }
}
CampoDescrição
data.idID do lote (o jobId do envio)
data.status"processing", "done" ou "failed"
data.total_recordsCNPJs válidos e únicos no lote
data.processedCNPJs já processados (inclui skipped)
data.foundEncontrados. Cada um consome 1 crédito no padrão (custo do seu plano no dashboard)
data.not_foundNão encontrados. Não consomem crédito.
data.skippedNão consultados porque o saldo acabou durante o lote (sem overage). Não consomem crédito.
data.errorMotivo da falha quando status é "failed"
data.file_name, data.formatRótulos enviados no POST
data.created_at, data.updated_atDatas ISO 8601
data.cnpjs[]Resultado de cada CNPJ processado: cnpj (14 caracteres sem máscara), found e data, que é o mesmo registro da Consulta de CNPJ ou null quando found é false

Durante "processing", os contadores atualizam em intervalos e podem ficar atrás de cnpjs.

Erros

StatusQuando aconteceO que fazer
400cnpjs ausente, vazio, não é array ("Campo 'cnpjs' deve ser um array não vazio.") ou tem mais de 10.000 itens ("Limite de 10000 CNPJs por lote excedido.")Corrija o body.
401API Key ausente, inválida ou inativa (error string)Confira o header x-api-key.
403Sem overage: saldo menor que o lote (error.message: "Créditos insuficientes para o lote: N necessários."). Também saldo zerado e conta inativa/bloqueada. Só no POST.Recarregue créditos ou reduza o lote.
404jobId não existe ou foi criado com outra API Key ("Lote não encontrado.")Confira o jobId e a chave.
422Nenhum CNPJ válido na lista ("Nenhum CNPJ válido na lista enviada.")Corrija a lista.
429Limite por minuto excedido, ou limite de lotes pendentes ("Limite de N lotes pendentes por cliente excedido."). Só no POST.Espere os segundos do header Retry-After (60 s no limite de lotes pendentes). Deixe os lotes anteriores terminarem antes de enviar outros.
500"Falha ao criar lote." Nenhum lote foi criado.Tente de novo. Reporte se persistir.

Formato do erro e retentativas: Códigos de Erro. Limite por minuto e créditos: Limites de Uso.

Detalhes

Estados do lote

SituaçãoComo identificarO que fazer
Em processamentostatus: "processing"Continue o polling. cnpjs já traz resultados parciais.
Concluído"done" e skipped: 0Use cnpjs.
Concluído com pulados"done" e skipped > 0Saldo acabou durante o lote. Recarregue e reenvie só os CNPJs que faltaram.
Falhou"failed"Leia error. Os encontrados em cnpjs já foram cobrados. Reenvie só os que faltaram.

Com overage, nenhum CNPJ é pulado: todos são consultados e o excedente é cobrado.

Casando os resultados com a sua lista

cnpjs não segue a ordem do envio e não inclui skipped nem não processados. Normalize sua lista (sem pontos, barra e traço, em maiúsculas) e case pelo campo cnpj. Os que faltarem são os que reenviar (inclui inválidos, que não custam nada).

const normalize = (cnpj: string) => cnpj.replace(/[./-]/g, '').toUpperCase()

const results = new Map(job.cnpjs.map((item) => [item.cnpj, item]))

for (const original of myCnpjs) {
  const result = results.get(normalize(original))
  console.log(original, result ? (result.found ? result.data.razao_social : 'não encontrado') : 'sem resultado')
}

// CNPJs para reenviar em um novo lote (se o lote falhou ou teve skipped)
const missing = [...new Set(myCnpjs.map(normalize))].filter((cnpj) => !results.has(cnpj))

Mais

  • Envio não idempotente: cada POST aceito cria um lote novo e cobra os encontrados. Se a conexão cair sem jobId, confira o dashboard ou GET /quota antes de reenviar. Com resposta de erro, nenhum lote foi criado.
  • Crédito: só found: true é cobrado, no mesmo custo e na mesma franquia da Consulta Simples de CPF. Inválidos, repetidos, não encontrados e skipped não.
  • Fonte dos dados: a mesma da Consulta de CNPJ: base pública mensal da Receita Federal, tratada pelo OpenCNPJ. Os dados podem estar defasados até a próxima atualização mensal.
  • Dados de exemplo: os CNPJs e os dados acima são fictícios.

Atualizado em 15 de outubro de 2026