[MX] CURP validation
Validate a person in Mexico from their CURP (Clave Única de Registro de Población). With one request, Brinta returns their social security number (NSS) and RFC, or their RFC with the legal name and postal code registered for it. Use it to onboard individuals, such as workers, drivers, sellers or freelancers, when you only have their CURP.
New to tax ID validations? Start with the generic guide.
Choose the validation_type
validation_typevalidation_type | You get back |
|---|---|
NSS | The person's NSS and RFC, plus name, phone, email and address when available |
RFC_FULL | The person's RFC, with the legal name and postal code registered for it |
Both use the same request. Only validation_type changes.
Request
curl -X POST https://api.brinta.com/tax-id-validations/ \
-H "Authorization: Bearer $BRINTA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"locations": ["MX"],
"validation_type": "NSS",
"company": {
"type": "person",
"legal_name": "JUAN PEREZ LOPEZ",
"phone": "525500000000",
"address": { "postal_code": "06600" },
"tax_registration": {
"number": "AAAA800101HDFXXX09",
"type": "CURP",
"level": "country",
"location": "MX"
},
"privacy_agreement": {
"url": "https://example.com/legal/privacy-policy",
"ip": "203.0.113.10"
}
}
}'Required fields
| Field | NSS | RFC_FULL | Notes |
|---|---|---|---|
company.tax_registration | ✅ | ✅ | number is the 18-character CURP, type: "CURP", level: "country", location: "MX". |
company.phone | ✅ | ✅ | The person's mobile, with country code and digits only: 525512345678. A leading + is accepted. No spaces or symbols. |
company.privacy_agreement.url | ✅ | ✅ | URL of the privacy notice the person accepted. |
company.privacy_agreement.ip | ✅ | ✅ | IP address from which they accepted it. |
company.legal_name | ✅ | The person's full name. | |
company.address.postal_code | ✅ | The person's postal code. | |
company.type | person. |
To use the same payload for both types, send all of the fields.
Consent is mandatory. These checks query personal records. Only sendprivacy_agreementwhen the person really accepted your privacy notice at that URL. Keep evidence of that acceptance on your side.
Send the person inline. The CURP validation needscompanywith the person's data and consent. It doesn't work withcompany_idorcompany_external_id, so nothing is stored on a company. To keep the result, save the returned registrations withPOST /companiesorPUT /companies/{id}.
Result
The POST answers right away with the validation id:
{ "id": "tiv2-5b0c9a7e-3f1d-4e8a-9c2b-7d6e5f4a3b21", "status": "in_process" }The NSS lookup can take from a few seconds to a few minutes. When it succeeds, Brinta notifies your validation webhook. Read the result with GET /tax-id-validations/{id}. Also poll that endpoint every few seconds until status is succeeded or failed, because failures must be read with GET.
NSS
NSS{
"id": "tiv2-5b0c9a7e-3f1d-4e8a-9c2b-7d6e5f4a3b21",
"status": "succeeded",
"data": [
{
"locationIsoCode": "MX",
"status": "succeeded",
"company": {
"name": "Juan Perez Lopez",
"legal_name": "Juan Perez Lopez",
"phone": "525500000000",
"tax_registrations": [
{ "number": "AAAA800101HDFXXX09", "type": "CURP", "level": "country", "location": "MX" },
{ "number": "00000000000", "type": "NSS", "level": "country", "location": "MX" },
{ "number": "AAAA800101XXX", "type": "RFC", "level": "country", "location": "MX" }
],
"address": { "postal_code": "06600", "address_line_1": "Calle Falsa 123", "neighborhood": "Juárez" }
},
"registry_lists": []
}
]
}RFC_FULL
RFC_FULL{
"id": "tiv2-0e1d2c3b-4a59-4687-b6c5-d4e3f2a1b0c9",
"status": "succeeded",
"data": [
{
"locationIsoCode": "MX",
"status": "succeeded",
"company": {
"legal_name": "JUAN PEREZ LOPEZ",
"tax_registrations": [
{ "number": "AAAA800101XXX", "type": "RFC", "level": "country", "location": "MX" }
],
"address": { "postal_code": "06600" }
},
"registry_lists": []
}
]
}tax_registrationsholds what was found. The NSS is 11 digits. An RFC for an individual is 13 characters.name,legal_nameandaddresscome from the official record. They can differ from what you sent; use the returned values.- Fields the source didn't return are left out.
When it fails
{
"id": "tiv2-5b0c9a7e-3f1d-4e8a-9c2b-7d6e5f4a3b21",
"status": "failed",
"data": [
{ "locationIsoCode": "MX", "status": "failed", "errors": ["curp: Formato de CURP inválido"], "registry_lists": [] }
]
}| Cause | What to do |
|---|---|
| The CURP is malformed or doesn't exist | Check the 18 characters with the person. They can download their CURP from gob.mx. |
| No records found for the person | The person may have no NSS (they never worked under IMSS) or no RFC. |
400 before the validation starts | A required field is missing, or the phone format is wrong. The message lists each field. |
Common mistakes
| Mistake | Fix |
|---|---|
"phone": "5512345678" (no country code) | Send 525512345678. |
Using company_id for a CURP validation | Send the person inline in company. |
"type": "NSS" in tax_registration | The NSS is a result, not an input. Send the CURP ("type": "CURP"). |
Missing legal_name or postal_code for RFC_FULL | Both are required. |
Sending privacy_agreement without real consent | Only send it when the person accepted your privacy notice. |
Updated about 5 hours ago
