CPFHub.io

Códigos de Error

La API sigue las convenciones REST estándar para los códigos de estado HTTP. Usa el estado HTTP para decidir qué hacer y el mensaje solo para logs o para mostrarlo.

Estructura de un error

Hay dos formatos. La mayoría de los errores traen error como objeto con message:

JSON
{
  "success": false,
  "data": null,
  "error": {
    "message": "CPF não encontrado na base de dados"
  }
}

Los errores de autenticación y de cuenta traen error como cadena: 401, 403 de cuenta inactiva o bloqueada, 403 "Limite de créditos excedido" (límite de créditos excedido) en el envío de lote con saldo en cero, 500 "Erro ao validar assinatura" (error al validar la suscripción) y 503 "usage_unavailable". El 403 de créditos en la Consulta Simple y en la Consulta en Tiempo Real viene como objeto.

JSON
{
  "success": false,
  "error": "API Key não fornecida"
}

Para leer el mensaje en ambos casos: typeof body.error === 'string' ? body.error : body.error?.message.

ℹ

Usa el estado HTTP

Decide el manejo según el estado HTTP. Los mensajes están en portugués y sirven para logs y para mostrarlos, así que no compares el texto en tu código. Las traducciones entre paréntesis de abajo son solo de referencia.

Referencia completa

2xx: Éxito

EstadoMensajeDescripción
200 OKNingunoConsulta exitosa. El campo data contiene los resultados.
202 AcceptedNingunoSolo en la consulta por lote: lote aceptado para procesamiento.

4xx: Errores del cliente

EstadoMensajeDescripción
400 Bad RequestCPF inválido. Deve conter 11 dígitos. (el CPF debe tener 11 dígitos)El CPF no tiene 11 dígitos después de quitar el formato.
400 Bad RequestData de nascimento inválida. Use o formato DD/MM/YYYY ou DDMMYYYY (fecha de nacimiento incorrecta, usa el formato DD/MM/YYYY o DDMMYYYY)Solo en la Consulta en Tiempo Real: birthDate ausente o inválido.
400 Bad RequestCampo 'cpfs' deve ser um array não vazio. (el campo cpfs debe ser un array no vacío)Solo en la consulta por lote: cpfs ausente, vacío o no es un array.
400 Bad RequestLimite de 10000 CPFs por lote excedido. (límite de 10.000 CPF por lote excedido)Solo en la consulta por lote: más de 10.000 CPF.
401 UnauthorizedAPI Key não fornecida (clave de API no enviada)Falta el header x-api-key. error es una cadena.
401 UnauthorizedAPI Key inválida (clave de API inválida)La clave de API no existe. error es una cadena.
401 UnauthorizedAPI Key inativa (clave de API inactiva)La clave de API fue reemplazada por una nueva en el dashboard. error es una cadena.
403 ForbiddenLimite de créditos excedido (límite de créditos excedido)Saldo menor que el costo de la consulta, en planes sin excedente. En la Consulta Simple y en la Consulta en Tiempo Real, error es un objeto. En el envío de lote con saldo insuficiente para una sola consulta, error es una cadena.
403 ForbiddenCréditos insuficientes para o lote: N necessários. (créditos insuficientes para el lote: se necesitan N)Solo en la consulta por lote: el saldo no cubre todos los CPF válidos de la lista, en planes sin excedente.
403 ForbiddenUsuário inativo. Entre em contato com o suporte. (usuario inactivo, contacta a soporte)Cuenta desactivada. error es una cadena.
403 ForbiddenConta bloqueada. Entre em contato com o suporte. (cuenta bloqueada, contacta a soporte)Cuenta bloqueada. error es una cadena.
404 Not FoundCPF não encontrado na base de dados (CPF no encontrado en la base de datos)Solo en la Consulta Simple. No consume crédito.
404 Not FoundLote não encontrado. (lote no encontrado)Solo en el estado del lote: el jobId no existe o se creó con otra clave de API. En raros casos de falla interna también aparece, así que repite una vez antes de tratar el lote como inexistente.
422 Unprocessable EntityCPF inválido. Dígito verificador incorreto. (dígito verificador incorrecto)El CPF falló la validación matemática de los dígitos verificadores.
422 Unprocessable EntityNenhum CPF válido na lista enviada. (ningún CPF válido en la lista enviada)Solo en la consulta por lote: ningún elemento de la lista es un CPF válido.
422 Unprocessable EntityMensaje de la Receita FederalSolo en la Consulta en Tiempo Real: la Receita rechazó la consulta, por ejemplo porque la fecha de nacimiento no coincide. No consume crédito.
429 Too Many RequestsLimite de requisições por minuto excedido. Tente novamente em N segundos. (límite de solicitudes por minuto excedido, intenta de nuevo en N segundos)Superaste el límite por minuto de la Consulta Simple, de la Consulta en Tiempo Real o del envío de lote. Trae el header Retry-After. No consume crédito.

Una ruta que no existe responde 404 con el texto plano NOT_FOUND, sin JSON. Revisa el Content-Type antes de leer el cuerpo como JSON.

5xx: Errores del servidor

EstadoMensajeDescripción
500 Internal Server ErrorErro ao validar assinatura (error al validar la suscripción)Falla interna al leer tu plan. error es una cadena.
500 Internal Server ErrorBanco de dados indisponível (base de datos no disponible)Falla interna en la Consulta Simple.
500 Internal Server ErrorFalha ao criar lote. (falla al crear el lote)Solo en la consulta por lote: no se pudo crear el lote.
502 Bad GatewayFalha ao interpretar a resposta da Receita Federal. (falla al interpretar la respuesta de la Receita Federal)Solo en la Consulta en Tiempo Real. No consume crédito.
502 / 503A Receita Federal não respondeu a tempo. Tente novamente em alguns segundos. Nenhum crédito foi cobrado. (la Receita Federal no respondió a tiempo, intenta de nuevo en unos segundos, no se cobró ningún crédito)Solo en la Consulta en Tiempo Real. No consume crédito.
502 / 503A Receita Federal está com alta demanda agora. Tente novamente em alguns segundos. Nenhum crédito foi cobrado. (la Receita Federal tiene alta demanda ahora, intenta de nuevo en unos segundos, no se cobró ningún crédito)Solo en la Consulta en Tiempo Real. No consume crédito.
503 Service UnavailableNão foi possível reservar os créditos. Tente novamente. (no fue posible reservar los créditos, intenta de nuevo)Falla interna al reservar los créditos de la consulta. No consume crédito.
503 Service UnavailableFalha ao registrar validação (falla al registrar la consulta)Falla interna al guardar la consulta. No consume crédito.
503 Service Unavailableusage_unavailableNo fue posible verificar el saldo de créditos. No consume crédito.

El 503 de saldo no disponible trae error como cadena y un campo message:

JSON
{
  "success": false,
  "error": "usage_unavailable",
  "message": "Não foi possível verificar o saldo de créditos. Tente novamente."
}

Ejemplo de manejo de errores

TypeScript
const res = await fetch(`https://api.cpfhub.io/cpf/${cpf}`, {
  headers: { 'x-api-key': process.env.CPFHUB_API_KEY! },
  signal: AbortSignal.timeout(10_000),
})
const isJson = res.headers.get('content-type')?.includes('application/json')
const body = isJson ? await res.json() : null

if (res.ok) {
  console.log(body.data.name)
} else {
  // error es cadena en algunos errores y objeto { message } en los demás
  const message = typeof body?.error === 'string' ? body.error : body?.error?.message

  switch (res.status) {
    case 404:
      // CPF no encontrado: no consume crédito
      break
    case 400:
    case 422:
      // Entrada incorrecta: corrígela, no repitas
      break
    case 401:
    case 403:
      // Clave incorrecta, créditos agotados o cuenta bloqueada: no repitas
      throw new Error(message)
    case 429:
      // Límite por minuto: espera Retry-After segundos y repite
      await new Promise(r => setTimeout(r, Number(res.headers.get('retry-after') ?? 5) * 1000))
      break
    default:
      // 5xx: repite con backoff (ver la tabla de abajo)
      throw new Error(message ?? `HTTP ${res.status}`)
  }
}
Python
import os, time, requests

res = requests.get(
    f"https://api.cpfhub.io/cpf/{cpf}",
    headers={"x-api-key": os.environ["CPFHUB_API_KEY"]},
    timeout=10,
)
is_json = "application/json" in res.headers.get("content-type", "")
body = res.json() if is_json else {}

if res.ok:
    print(body["data"]["name"])
else:
    error = body.get("error")
    message = error if isinstance(error, str) else (error or {}).get("message")

    if res.status_code == 404:
        print("CPF no encontrado")
    elif res.status_code == 429:
        time.sleep(int(res.headers.get("retry-after", "5")))  # luego repite
    elif res.status_code >= 500:
        pass  # repite con backoff
    else:
        raise RuntimeError(message)

Reintentos

Estado¿Repetir?Cómo
429SíEspera el valor del header Retry-After
500, 502, 503 en un GET (Consulta Simple, estado del lote, saldo)Sí, hasta 3 vecesBackoff: 1 s, 2 s, 4 s
502, 503 recibidos en POST /cpf/realtimeSí, hasta 3 vecesBackoff: 2 s, 4 s, 8 s
400, 401, 403, 404, 422NoCorrige la entrada, la clave o el saldo
⚠

POST no es idempotente

POST /cpf/realtime y POST /cpf/bulk no aceptan clave de idempotencia. Si la conexión se cae o tu timeout se agota antes de la respuesta, la consulta pudo completarse y cobrarse, o el lote pudo haberse creado. Antes de repetir, revisa el saldo en GET /quota y, en el lote, los envíos recientes en el dashboard. Repite sin revisar solo cuando hayas recibido 429, 502 o 503.

Probar sin gastar créditos

No consumen crédito: 400, 401, 404, 422 y 429. Puedes probar el manejo de errores gratis:

PruebaSolicitudRespuesta
CPF con menos de 11 dígitosGET /cpf/123400
Dígito verificador incorrectoGET /cpf/11111111111422
Fecha de nacimiento inválidaPOST /cpf/realtime con {"cpf":"12345678909","birthDate":"1990-06"}400
Sin clave de APIcualquier ruta, sin el header x-api-key401
Saldo de la cuentaGET /quota200, siempre gratis
  • Una respuesta 200 consume crédito. El plan Gratis tiene 50 créditos para probar el camino de éxito.
  • El CPF 12345678909 de los ejemplos es ficticio. Para probar el éxito, usa un CPF cuyo titular haya autorizado la consulta.

Actualizado el 4 de octubre de 2026