CURP (RENAPO)
The CURP (Clave Única de Registro de Población) is Mexico's 18-character unique population identity key, issued and maintained by RENAPO (Registro Nacional de Población). Every Mexican citizen and foreign resident holds one.
Send a CURP and we return the registered name, gender, nationality, and date of birth — synchronously, no credentials of your own required.
Validate a CURP
POST /v1/curp
{ "curp": "XEXX010101HNEXXXA4" }
Pass include_pdf: true to also receive the official constancia PDF:
{ "curp": "XEXX010101HNEXXXA4", "include_pdf": true }
The curp field must be exactly 18 characters and match the standard CURP format
(AAAA######AAAAAA##). Laravel returns a 422 with field-level validation errors if the format
is invalid — no call to RENAPO is made.
Response (200 OK):
{
"curp": "XEXX010101HNEXXXA4",
"valid": true,
"name": "JUAN",
"last_name": "EJEMPLO",
"second_last_name": "DEMO",
"gender": "male",
"date_of_birth": "2001-01-01",
"nationality": "MEX",
"status": "active"
}
With include_pdf: true:
{
"curp": "XEXX010101HNEXXXA4",
"valid": true,
"name": "JUAN",
"last_name": "EJEMPLO",
"second_last_name": "DEMO",
"gender": "male",
"date_of_birth": "2001-01-01",
"nationality": "MEX",
"status": "active",
"pdf": {
"available": true,
"data": "JVBERi0xLjQ...",
"mime_type": "application/pdf",
"filename": "curp_XEXX010101HNEXXXA4.pdf",
"encoding": "base64"
}
}
If the PDF could not be retrieved: pdf.available is false and data, mime_type,
filename, encoding are null. The identity data is always returned regardless.
Field reference
| Field | Type | Description |
|---|---|---|
curp |
string | The CURP as stored in RENAPO (uppercased) |
valid |
bool | Always true on a 200 — a CURP that fails validation returns an error, not valid: false |
name |
string | First name(s) as registered |
last_name |
string | Paternal surname |
second_last_name |
string | Maternal surname |
gender |
"male" | "female" | "unknown" |
Derived from RENAPO's gender key (H/M) |
date_of_birth |
string (YYYY-MM-DD) | Date of birth from the RENAPO record |
nationality |
string | ISO nationality code (e.g. "MEX") |
status |
"active" | "unknown" |
RENAPO registration status (Alta Normal → active) |
Responses
Every non-2xx response carries a stable reason you can branch on directly:
| Status | reason |
What happened | What to do |
|---|---|---|---|
200 |
— | CURP found and valid | Use the identity fields |
404 |
not_found |
CURP is not registered in RENAPO | Verify the CURP with the person |
422 |
— (Laravel errors) |
curp field failed format validation |
Fix the request body |
429 |
rate_limited |
Too many requests to RENAPO | Back off and retry |
503 |
unavailable |
RENAPO is temporarily unreachable | Retry — same request will succeed once RENAPO is back |
503 |
upstream_error |
Unexpected error from the provider | Retry later; contact support if it persists |
Example (404):
{
"message": "Bad request: CURP no encontrado en el padrón",
"reason": "not_found"
}
CURP validation is synchronous — the result comes back in the response, so there is no CURP webhook. Webhooks are only for asynchronous SAT extractions.