CPFHub.io

CNPJ 批量查询

发送 最多 10,000 个 CNPJ(巴西企业税号)的列表,系统在后台处理,为每个 CNPJ 返回与 CNPJ 查询相同的记录。每查到一个 CNPJ 消耗 1 个积分。

正在使用 Cursor、Lovable、v0 或其他 AI 工具? 复制 CNPJ 批量查询的提示词,粘贴到您的 AI 助手中。

在 Cursor 中打开

如果不想写代码,可以在控制台提交 CNPJ 列表并查看每个 CNPJ 的结果。

两步流程:

  1. POST /cnpj/bulk 提交列表,并立即返回 jobId。
  2. GET /cnpj/bulk/{jobId} 返回进度和结果。重复调用,直到 status 为 "done" 或 "failed"。

端点

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

参数

位置名称必填说明
请求头x-api-key是您的 API 密钥。见身份认证。
请求头Content-Type是application/json
请求体cnpjs是CNPJ 的 string[],带或不带格式均可,支持纯数字或字母数字格式。不能为空,最多 10,000 个。非字符串项计为无效。
请求体fileName否自定义标签。在状态查询中以 file_name 返回。
请求体format否来源格式的自定义标签(例如 "csv")。以 format 返回。

提交时的处理

步骤效果
规范化去除点、斜杠和连字符,并将字母转换为大写。格式或校验位错误的 CNPJ 计入 invalid,不计费。
去重重复项会被移除。每个 CNPJ 只查询和计费一次。重复项既不计入 totalRecords,也不计入 invalid。
余额未开通超额用量时,余额必须覆盖 所有 有效 CNPJ(totalRecords × 查询费用,默认 1 个积分)。不足时返回 403,不扣任何积分。
待处理批次每个客户同时处理中的批次数有上限。超出时返回 429。

超过 10,000 个 CNPJ 时,请拆分为多批,每批发送一个 POST。如果收到 429,请等待之前的批次完成。

示例

读取 data 前请先检查状态码:出错时响应中没有 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"]
  }'

响应

HTTP 202 Accepted

JSON
{
  "success": true,
  "data": {
    "jobId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "processing",
    "totalRecords": 2,
    "invalid": 0
  }
}
字段类型说明
data.jobIdstring批次 ID。请保存,用于查询状态。
data.statusstring始终为 "processing"
data.totalRecordsnumber将被查询的有效且不重复的 CNPJ 数量
data.invalidnumber被丢弃的项数(格式错误、校验位错误或非字符串)

提交接口的响应使用 camelCase,状态接口的响应使用 snake_case。

状态与结果

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

请使用提交时的同一个 API 密钥。该接口不消耗积分,余额为零时也可使用。

轮询:

  • 初始间隔 5 秒,大批次可逐步增加到 30 秒。每次调用都会返回完整的 cnpjs 数组,而每条 CNPJ 记录都比 CPF 记录大得多。
  • 在客户端设置最长等待时间(例如 30 分钟)。批次耗时取决于提交的 CNPJ 数量。
  • 遇到 5xx 或网络错误时,在下一轮重试即可。GET 可以安全地重复调用。
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",
          "...": "other CNPJ Lookup fields"
        }
      },
      {
        "cnpj": "12ABC34501DE35",
        "found": false,
        "data": null
      }
    ]
  }
}
字段说明
data.id批次 ID(即提交时返回的 jobId)
data.status"processing"、"done" 或 "failed"
data.total_records批次中有效且不重复的 CNPJ 数量
data.processed已处理的 CNPJ 数量(包括 skipped)
data.found查到的数量。默认每个消耗 1 个积分(您套餐的费用见控制台)
data.not_found未查到的数量。不消耗积分。
data.skipped因批次处理中余额用完(未开通超额用量)而未查询的数量。不消耗积分。
data.errorstatus 为 "failed" 时的失败原因
data.file_name, data.formatPOST 中发送的标签
data.created_at, data.updated_atISO 8601 格式日期
data.cnpjs[]每个已处理 CNPJ 的结果:cnpj(14 个字符,不带格式)、found 和 data。data 与 CNPJ 查询返回的记录相同,found 为 false 时为 null

状态为 "processing" 时,计数器按一定间隔更新,可能落后于 cnpjs。

错误

API 只返回葡萄牙语信息。错误信息按原样列出。

状态码触发场景处理方式
400cnpjs 缺失、为空、不是数组("Campo 'cnpjs' deve ser um array não vazio.")或超过 10,000 项("Limite de 10000 CNPJs por lote excedido.")修正请求体。
401API 密钥缺失、无效或已停用(error 为字符串)检查 x-api-key 请求头。
403未开通超额用量:余额少于批次所需(error.message:"Créditos insuficientes para o lote: N necessários.",积分不足)。余额为零以及账户停用/封禁时也会返回。仅限 POST。补充积分或缩小批次。
404jobId 不存在,或由其他 API 密钥创建("Lote não encontrado.")检查 jobId 和密钥。
422列表中没有有效 CNPJ("Nenhum CNPJ válido na lista enviada.")修正列表。
429超出每分钟限制,或超出待处理批次上限("Limite de N lotes pendentes por cliente excedido.")。仅限 POST。等待 Retry-After 请求头给出的秒数(待处理批次上限为 60 秒)。请等之前的批次完成后再提交。
500"Falha ao criar lote."(创建批次失败)。未创建批次。重试。如持续出现,请反馈给我们。

错误格式和重试策略见错误码。每分钟限制和积分规则见使用限制。

补充说明

批次状态

状态判断方式处理方式
处理中status: "processing"继续轮询。cnpjs 中已有部分结果。
已完成"done" 且 skipped: 0使用 cnpjs。
已完成但有跳过项"done" 且 skipped > 0批次处理中余额用完。补充积分后,只重新提交缺失的 CNPJ。
失败"failed"读取 error。cnpjs 中已查到的项 已经计费。只重新提交缺失的部分。

开通超额用量时不会跳过任何 CNPJ:所有 CNPJ 都会被查询,超出部分按超额用量计费。

将结果与您的列表对应

cnpjs 不按提交顺序返回,也不包含 skipped 项和未处理项。请将您的列表规范化(去除点、斜杠和连字符,并转为大写),然后按 cnpj 字段匹配。缺失的就是需要重新提交的(其中也包括无效项,无效项不计费)。

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 : 'not found') : 'no result')
}

// CNPJs to resend in a new batch (if the batch failed or had skipped items)
const missing = [...new Set(myCnpjs.map(normalize))].filter((cnpj) => !results.has(cnpj))

其他说明

  • 提交不是幂等的: 每个被受理的 POST 都会创建新批次,并对查到的 CNPJ 计费。如果连接中断且未拿到 jobId,重新提交前请先查看控制台或 GET /quota。如果收到的是错误响应,则没有创建批次。
  • 积分: 只有 found: true 计费,费用和额度与 CPF 标准查询相同。无效、重复、未查到和 skipped 项都不计费。
  • 数据来源: 与 CNPJ 查询相同,即 Receita Federal(巴西联邦税务局)每月发布的公开数据库,由 OpenCNPJ 处理。在下一次月度更新前,数据可能不是最新的。
  • 示例数据: 上方的 CNPJ 和数据均为虚构。

更新于 2026 年 10 月 15 日