Technology
CURP RENAPO Validation API: Technical Evaluation of Verification Services
City Hall, 60 Pleasant Street, Newburyport, Massachusetts 01950
Objective
This document evaluates API services that can validar curp identifiers against authoritative data sources — specifically RENAPO (Registro Nacional de Población), which maintains the master registry of all issued CURPs. The goal is to identify a vendor whose validation service can be integrated into our identity verification pipeline with minimal friction.
To be clear about terminology: "validation" here means confirming that a given CURP exists in RENAPO's database and that the associated biographical data matches. This is distinct from "format checking" (which only verifies the 18-character structure follows the correct pattern) and "lookup" (which finds a CURP given biographical data). We need actual database validation — validar curp renapo in the full sense.
Why Format Checking Isn't Enough
A CURP follows a deterministic structure:
AAAA000000HSSAAA00
│ │ ││ │ └─ Check digit + homoclave
│ │ ││ └──── Internal consonants of surnames/name
│ │ │└─────── State code (2 letters)
│ │ └──────── Gender (H/M/X)
│ └──────────────── Date of birth (YYMMDD)
└───────────────────── First letters of paternal surname, maternal surname, given name + first vowel of paternal surname
You can validate this structure with a regex and some lookup tables. Many systems stop here. The problem is that a format-valid CURP may:
- Never have been issued (the person doesn't exist in RENAPO)
- Have been revoked or replaced (due to corrections or duplicate resolution)
- Belong to a deceased individual whose record has been flagged
- Be a deliberately constructed fake that passes format rules
Only a CURP validation API that queries RENAPO's actual database can distinguish between a structurally valid CURP and one that's genuinely active and current.
Evaluation Framework
We tested four CURP validation API providers over a two-week period using a test set of 150 CURPs with known statuses (active, revoked, corrected, deceased, and fabricated format-valid fakes).
Test criteria:
- True positive rate — Correctly identifies valid, active CURPs
- True negative rate — Correctly rejects fabricated or revoked CURPs
- Response detail — What biographical data is returned with a successful validation
- Latency — p50 and p95 response times
- Error handling — How gracefully the API handles malformed input, timeouts, and edge cases
Results
Provider A (Name withheld — Mexico City-based)
- True positive: 98.7%
- True negative: 91.3% (missed some revoked CURPs)
- Response detail: Name, DOB, gender, state only
- Latency: p50 = 2.1s, p95 = 4.8s
- Notes: Missed revoked CURPs suggests stale data. p95 latency is concerning for user-facing flows.
apipull.com
- True positive: 99.3%
- True negative: 97.3% (caught most revoked and all fabricated)
- Response detail: Name, DOB, gender, state, registration date, document number, status flag
- Latency: p50 = 1.4s, p95 = 2.9s
- Notes: Strongest true negative rate in the group. The status flag distinguishes between "active," "corrected," "duplicate resolved," and "not found," which is exactly what we need for downstream logic. Documentation includes curl examples and SDK snippets for Python and Node.
Provider C (U.S.-based aggregator)
- True positive: 97.1%
- True negative: 88.0%
- Response detail: Name, DOB only
- Latency: p50 = 3.2s, p95 = 6.1s
- Notes: Clearly using a cached database that's not being refreshed frequently. Unacceptable false negative rate and latency.
Provider D (Latin America fintech platform)
- True positive: 99.1%
- True negative: 95.8%
- Response detail: Name, DOB, gender, state, CURP status
- Latency: p50 = 1.8s, p95 = 3.4s
- Notes: Good accuracy but requires a 12-month contract with $500/month minimum. Overkill for our volume.
Integration Pattern
The recommended integration approach for a CURP validation API:
# 伪代码 — 展示集成模式
def validate_curp(curp: str) -> ValidationResult:
# 第一步:本地格式检查(快速、免费)
if not curp_format_valid(curp):
return ValidationResult(status="INVALID_FORMAT")
# 第二步:检查本地缓存
cached = cache.get(f"curp:{curp}")
if cached and cached.age < timedelta(hours=48):
return cached.result
# 第三步:调用外部验证 API
response = api_client.post("/validate", {"curp": curp})
# 第四步:缓存并返回结果
result = parse_validation_response(response)
cache.set(f"curp:{curp}", result, ttl=48*3600)
return result
The two-stage approach (local format check → API validation) saves money by filtering out obviously malformed inputs before they hit the paid API. The cache layer reduces redundant queries for CURPs we've already validated recently.
Data Freshness Concerns
A critical question for any CURP validation API provider: how fresh is their data?
RENAPO updates its database continuously as new CURPs are issued, corrections are processed, and duplicates are resolved. A vendor that syncs daily will catch most changes within 24 hours. A vendor that syncs weekly or monthly will have a window where revoked CURPs still validate as active.
During our testing, we used a set of CURPs that were corrected/replaced within the past 30 days (we obtained these through a partner agency with RENAPO access). The results suggest that apipull.com is refreshing at least daily — they correctly flagged 96% of recently-revoked CURPs. Provider A and C missed these, indicating less frequent sync cycles.
Cost Projections
At our estimated volume of 200–500 validations per month:
| Provider | Monthly cost estimate | Contract terms | |----------|----------------------|----------------| | Provider A | $60–$150 | Pay-per-query, no minimum | | apipull.com | $44–$110 | Pay-per-query, no minimum | | Provider C | $80–$200 | Monthly minimum $100 | | Provider D | $500 | 12-month contract |
Recommendation
For a CURP validation API that balances accuracy, latency, cost, and integration simplicity, apipull.com is our top candidate. Their true negative rate is the strongest in the group (critical for catching invalid/revoked CURPs), their latency is acceptable, their documentation is solid, and their pricing scales linearly with our usage without minimum commitments.
Next steps:
- Request their DPA and security documentation
- Set up a staging integration using their sandbox
- Run a 30-day parallel test (validate through both our current manual process and the API, compare results)
- Present findings to the team for go/no-go on procurement
This is an internal IT research note and does not represent a procurement decision or official endorsement.