CNPJ 批量查询
发送 最多 10,000 个 CNPJ(巴西企业税号)的列表,系统在后台处理,为每个 CNPJ 返回与 CNPJ 查询相同的记录。每查到一个 CNPJ 消耗 1 个积分。
正在使用 Cursor、Lovable、v0 或其他 AI 工具? 复制 CNPJ 批量查询的提示词,粘贴到您的 AI 助手中。
如果不想写代码,可以在控制台提交 CNPJ 列表并查看每个 CNPJ 的结果。
两步流程:
POST /cnpj/bulk提交列表,并立即返回jobId。GET /cnpj/bulk/{jobId}返回进度和结果。重复调用,直到status为"done"或"failed"。
端点
POST
https:/ / 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.jobId | string | 批次 ID。请保存,用于查询状态。 |
data.status | string | 始终为 "processing" |
data.totalRecords | number | 将被查询的有效且不重复的 CNPJ 数量 |
data.invalid | number | 被丢弃的项数(格式错误、校验位错误或非字符串) |
提交接口的响应使用 camelCase,状态接口的响应使用 snake_case。
状态与结果
GET
https:/ / 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.error | status 为 "failed" 时的失败原因 |
data.file_name, data.format | POST 中发送的标签 |
data.created_at, data.updated_at | ISO 8601 格式日期 |
data.cnpjs[] | 每个已处理 CNPJ 的结果:cnpj(14 个字符,不带格式)、found 和 data。data 与 CNPJ 查询返回的记录相同,found 为 false 时为 null |
状态为 "processing" 时,计数器按一定间隔更新,可能落后于 cnpjs。
错误
API 只返回葡萄牙语信息。错误信息按原样列出。
| 状态码 | 触发场景 | 处理方式 |
|---|---|---|
400 | cnpjs 缺失、为空、不是数组("Campo 'cnpjs' deve ser um array não vazio.")或超过 10,000 项("Limite de 10000 CNPJs por lote excedido.") | 修正请求体。 |
401 | API 密钥缺失、无效或已停用(error 为字符串) | 检查 x-api-key 请求头。 |
403 | 未开通超额用量:余额少于批次所需(error.message:"Créditos insuficientes para o lote: N necessários.",积分不足)。余额为零以及账户停用/封禁时也会返回。仅限 POST。 | 补充积分或缩小批次。 |
404 | jobId 不存在,或由其他 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 日