Skip to content
BrazID

API documentation

A single endpoint, authenticated with a key. Every response is JSON.

Authentication

Send your key in the x-api-key header on every request. Missing, invalid or revoked keys receive 401. Create and revoke keys in the dashboard and keep them on your server only.

x-api-key: cpf_live_••••••••••••••••

Endpoints

There are two paths: a fast lookup in our own database (CPF only) and the official lookup (CPF + date of birth). Both have a batch version with up to 1,000 CPFs per request. Every CPF is sanitized (dots and dashes removed) before lookup.

GET /v1/cpf/:cpf

Fast lookup in the internal database

Searches the cache only (Redis and Neon), in milliseconds. No date of birth. If the CPF is not in the database it answers 404 with the CACHE_MISS code, and you use POST /v1/cpf.

200 uses 1 credit; 404 is free.

POST /v1/cpf/batch

Fast batch lookup (internal database)

Takes { "cpfs": [...] } and returns found (records found), missing (not in cache) and invalid (malformed CPFs or bad check digit).

1 credit per CPF found; missing and invalid are free.

POST /v1/cpf

Official lookup

Send cpf and birthdate (YYYY-MM-DD, both required). It uses the cache when the record exists and is under 30 days old; otherwise it queries the official source and updates the cache.

Only the 200 uses 1 credit.

POST /v1/cpf/batch/process

Official batch lookup (asynchronous)

Takes an array [{ "cpf": "...", "birthdate": "YYYY-MM-DD" }] with up to 1,000 items and answers 202 with a batch_id. Track it with GET /v1/cpf/batch/:id or by webhook.

Requires credits for the whole batch (or a plan with overage). 1 credit per item found.

Lookup in the internal database

The cache-miss 404 is not a CPF error: it only means the record is not in our database yet. The body carries code: "CACHE_MISS". Cached data is valid for up to 30 days.

curl https://api.brazid.com/v1/cpf/52998224725 \
  -H "x-api-key: $BRAZID_API_KEY"

Batch lookup

For the internal-database batch the response is immediate. Repeated CPFs count once. Without overage, if the balance does not cover all the records found, the whole request answers 402 and nothing is charged.

curl -X POST https://api.brazid.com/v1/cpf/batch \
  -H "x-api-key: $BRAZID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cpfs": ["529.982.247-25", "11144477735"] }'
{
  "success": true,
  "found": [
    {
      "cpf": "52998224725",
      "name": "MARIA SOUZA LIMA",
      "birthdate": "26/11/1982",
      "situation": "REGULAR"
    }
  ],
  "missing": [
    "11144477735"
  ],
  "invalid": [],
  "credits_remaining": 48
}

How the official batch works

Whatever is already cached is answered right away. The rest goes to the official source in the background, with limited concurrency. Invalid items, not-found items and provider failures are free, and you can resend only the ones that failed. Results stay available for 24 hours. If you have a webhook configured, we send the batch.completed event (without personal data) when the batch finishes.

curl -X POST https://api.brazid.com/v1/cpf/batch/process \
  -H "x-api-key: $BRAZID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[{ "cpf": "529.982.247-25", "birthdate": "1982-11-26" }, { "cpf": "11144477735", "birthdate": "1990-05-02" }]'
{
  "success": true,
  "batch_id": "0c1e…",
  "status": "processing",
  "total": 2,
  "processed": 1,
  "status_url": "/v1/cpf/batch/0c1e…"
}

Look up a CPF

Send cpf (with or without punctuation) and birthdate (YYYY-MM-DD), both required. Both are sanitized and validated before any lookup; the date of birth must match the holder’s, otherwise the response is 404.

POST /v1/cpf

curl -X POST https://api.brazid.com/v1/cpf \
  -H "x-api-key: $BRAZID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cpf": "529.982.247-25", "birthdate": "1982-11-26" }'

Response

credits_remaining can be hidden in the dashboard settings. gender and deceased may be null when the source does not provide them.

{
  "success": true,
  "data": {
    "cpf": "52998224725",
    "name": "MARIA SOUZA LIMA",
    "birthdate": "26/11/1982",
    "day": 26,
    "month": 11,
    "year": 1982,
    "gender": "M",
    "deceased": false,
    "situation": "REGULAR"
  },
  "credits_remaining": 49
}
cpf
Sanitized CPF, 11 digits.
name
Holder name, uppercase.
birthdate
Date of birth as DD/MM/YYYY. day, month and year carry the numeric parts.
gender
M, F or null.
situation
Registration status as text (e.g. REGULAR, TITULAR FALECIDO); null when the source does not provide it.
deceased
true when the registration status indicates death; null when unknown.
credits_remaining
Balance after this lookup (monthly quota + bonus credits).

Errors

No 4xx or 5xx response uses a credit or triggers overage billing.

StatusWhen it happensUses credit
200—Yes (1)
400The CPF does not have exactly 11 numeric digits, or birthdate is missing or invalid (use YYYY-MM-DD).{ "error": "Invalid CPF format", "message": "CPF deve conter exatamente 11 dígitos numéricos" } / { "error": "Invalid birthdate", "message": "birthdate é obrigatório e deve ser uma data válida no formato AAAA-MM-DD" }No
401Missing x-api-key header, invalid or revoked key.{ "error": "Invalid or missing API key" }No
402Free plan with all 20 credits of the cycle used (they renew next cycle). Move to a Pro plan to continue (paid plans never get this error: extra lookups are billed).{ "error": "Payment Required", "message": "Limite de créditos excedido", "code": "CREDITS_EXHAUSTED" }No
403Suspended or blocked account.{ "error": "Forbidden", "message": "Limite de créditos excedido" }No
404Valid CPF, but not found in the official registry.{ "error": "CPF not found" }No
422Invalid check digit.{ "error": "Invalid check digit" }No
429Your plan’s requests-per-second limit was exceeded. Honor the Retry-After header.{ "error": "Rate limit exceeded", "message": "Muitas requisições. Aguarde antes de tentar novamente." }No
500 / 503Temporary failure in our infrastructure or the external provider.{ "error": "Service unavailable", "message": "Falha temporária no processamento. Tente novamente em instantes." }No

Rate limits

Each key has a per-second limit based on the plan: 5 (Free), 20 (Pro 200), 50 (Pro 1,000), 100 (Pro 5,000), 200+ (Corporate). Responses include X-RateLimit-Limit, X-RateLimit-Remaining and, on 429, Retry-After in seconds.

Usage webhooks

Register an HTTPS URL in the dashboard to receive the usage.threshold_reached event when usage reaches 80% and 95% of your quota. Each delivery carries x-brazid-signature: t=<timestamp>,v1=<HMAC-SHA256 of "timestamp.body">, signed with your webhook secret.

{
  "type": "usage.threshold_reached",
  "threshold": 80,
  "used_percent": 80,
  "monthly_credits": 500,
  "auto_charge_enabled": true,
  "period_end": "2026-11-13T00:00:00.000Z"
}