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.
| Status | When it happens | Uses credit |
|---|---|---|
| 200 | — | Yes (1) |
| 400 | The 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 |
| 401 | Missing x-api-key header, invalid or revoked key.{ "error": "Invalid or missing API key" } | No |
| 402 | Free 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 |
| 403 | Suspended or blocked account.{ "error": "Forbidden", "message": "Limite de créditos excedido" } | No |
| 404 | Valid CPF, but not found in the official registry.{ "error": "CPF not found" } | No |
| 422 | Invalid check digit.{ "error": "Invalid check digit" } | No |
| 429 | Your 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 / 503 | Temporary 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"
}