# CURP

> Servicio de consulta y validación oficial de la Clave Única de Registro de Población (CURP) en tiempo real. Esta API permite verificar la autenticidad, vigencia y datos biométricos/registrales asociados ante el Registro Nacional de Población (RENAPO).

API publicada en idoo.dev por Rodrigo Montelongo (categoría: General).
Página: https://idoo.dev/apis/curp

## Cómo llamar a la API

- **URL:** `https://idoo.dev/v1/curp/{ruta}` — cualquier método HTTP; query, body y `Content-Type` llegan intactos a la API.
- **Autenticación:** header `Authorization: Bearer {api_key}` (o `X-API-KEY: {api_key}`). Una sola key de idoo.dev sirve para todas las APIs a las que estés suscrito.
- **Ambiente según la key:** `idoo_sk_test_...` → sandbox (gratis, no descuenta cuota); `idoo_sk_live_...` → producción.
- **Seguridad:** guarda la key en una variable de entorno (p. ej. `IDOO_API_KEY`) y llama a la API solo desde el servidor; nunca la expongas en el frontend ni la subas al repositorio.
- **Obtener acceso:** inicia sesión en https://idoo.dev/login, suscríbete a la API en https://idoo.dev/apis/curp y crea tu key en https://idoo.dev/panel/apikeys.

## Respuestas

La respuesta de la API se devuelve **tal cual** (status, headers y body del proveedor). Solo los errores del propio gateway usan este sobre JSON:

```json
{"valid": false, "status": 402, "message": "…", "data": null, "timestamp": "2026-01-01 12:00:00"}
```

| Status | Causa | Qué hacer |
|---|---|---|
| 401 | No se envió la key | Agrega el header `Authorization: Bearer {api_key}` |
| 403 | Key inválida o revocada, o sin suscripción activa a la API | Revisa la key y la suscripción en el panel |
| 402 | Cuota mensual agotada (`data.periodo_reinicia` indica cuándo se renueva) | Mejora el plan o compra un paquete; no reintentes |
| 404 | La API no existe o no está publicada | Revisa el slug de la URL |
| 429 | Rate limit por minuto excedido | Espera los segundos del header `Retry-After` y reintenta |
| 502 | La API no respondió o no tiene URL para tu ambiente | Reintenta con backoff; si persiste, contacta al creador |

Headers útiles en cada respuesta: `X-RateLimit-Limit`, `X-RateLimit-Remaining` y `X-Idoo-Cuota-Restante` (si el plan tiene cuota).
Solo descuentan cuota las llamadas de producción que la API responde con 2xx/3xx; los errores no se cobran.

## Planes

| Plan | Precio (MXN) | Llamadas/mes | Peticiones/min |
|---|---|---|---|
| Free | Gratis | 50 | 2 |
| BASICO | $199.00/mes | 1,000 | 30 |
| PRO | $499.00/mes | 5,000 | 60 |
| MAX | $999.00/mes | 15,000 | 60 |
| PLUS | $2,500.00/mes | 50,000 | 120 |

## Documentación

## API de Consulta y Validación de CURP (México)

Servicio de consulta y validación oficial de la Clave Única de Registro de Población (CURP) en tiempo real. Esta API permite verificar la autenticidad, vigencia y datos biométricos/registrales asociados ante el Registro Nacional de Población (RENAPO).

La API se encuentra integrada con el gateway de [idoo.dev](https://idoo.dev), por lo que toda la autenticación, cuotas de plan y control de límites (rate limiting) son gestionados automáticamente mediante tu API Key de idoo.dev.

---

### Autenticación

Todas las llamadas deben realizarse a través del gateway de **idoo.dev** incluyendo tu clave de API en el encabezado `X-Idoo-Key`:

```http
X-Idoo-Key: tu_api_key_aqui
```

> **Nota para desarrolladores:** En ambiente `sandbox`, utiliza las credenciales de prueba proporcionadas por idoo.dev.

---

### Endpoint: Consulta por CURP

Permite obtener los datos de identidad y registro civil de una persona física mediante su CURP de 18 caracteres.

#### Información General

- **Método HTTP:** `GET`
- **Ruta relativa:** `/v2/rest/curp/porCurp/{curp}`
- **Ruta alternativa (Query string):** `/v2/rest/curp/porCurp?curp={curp}`
- **URL Base en idoo.dev:** `https://api.idoo.dev/v1/{slug-de-tu-api}`
- **Content-Type / Accept:** `application/json`

---

#### Parámetros de la Petición

| Parámetro | Tipo | Ubicación | Obligatorio | Descripción | Ejemplo |
|---|---|---|---|---|---|
| `curp` | `string` | Path o Query | **Sí** | Cadena alfanumérica de 18 caracteres con el formato oficial de CURP. | `ROMA900101HDFRRN01` |

##### Formato esperado de la CURP:
- Longitud: Exactamente 18 caracteres.
- Patrón (RegEx): `^[A-Z]{4}\d{6}[HMX][A-Z]{5}[A-Z0-9]\d$`

---

#### Ejemplos de Petición

##### cURL
```bash
curl -X GET "https://api.idoo.dev/v1/{slug-de-tu-api}/v2/rest/curp/porCurp/ROMA900101HDFRRN01" \
  -H "X-Idoo-Key: tu_api_key_aqui" \
  -H "Accept: application/json"
```

##### JavaScript (Node.js / Fetch)
```javascript
const response = await fetch('https://api.idoo.dev/v1/{slug-de-tu-api}/v2/rest/curp/porCurp/ROMA900101HDFRRN01', {
  method: 'GET',
  headers: {
    'X-Idoo-Key': 'tu_api_key_aqui',
    'Accept': 'application/json'
  }
});

const data = await response.json();
console.log(data);
```

##### Python (Requests)
```python
import requests

url = "https://api.idoo.dev/v1/{slug-de-tu-api}/v2/rest/curp/porCurp/ROMA900101HDFRRN01"
headers = {
    "X-Idoo-Key": "tu_api_key_aqui",
    "Accept": "application/json"
}

response = requests.get(url, headers=headers)
print(response.json())
```

---

#### Pruebas en Ambiente Sandbox

En el ambiente **sandbox**, puedes utilizar la siguiente CURP de prueba sintética para validar tu flujo de integración sin consumir créditos reales:

- **CURP de Prueba:** `AAAA000000HDFRRR01`

---

#### Respuestas de la API

Todas las respuestas de la API utilizan un sobre JSON consistente:

```json
{
  "valid": true,
  "status": 200,
  "message": "Mensaje descriptivo",
  "data": { ... },
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

##### Respuesta Exitosa (200 OK)

```json
{
  "valid": true,
  "status": 200,
  "message": "CURP localizada exitosamente",
  "data": {
    "Curp": "ROMA900101HDFRRN01",
    "ApellidoPaterno": "RODRIGUEZ",
    "ApellidoMaterno": "MARTINEZ",
    "Nombre": "ALEJANDRO",
    "Sexo": "H",
    "FechaNacimiento": "01/01/1990",
    "Nacionalidad": "MEX",
    "DocProbatorio": "1",
    "AnioReg": "1990",
    "Foja": "12",
    "Tomo": "3",
    "Libro": "5",
    "NumActa": "345",
    "CRIP": "0900123456789",
    "NumEntidadReg": "09",
    "CveMunicipioReg": "005",
    "NumRegExtranjeros": "",
    "FolioCarta": "",
    "CveEntidadEmisora": "DF",
    "StatusCurp": "AN",
    "Historicos": []
  },
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

##### Descripción de Campos en `data`

| Campo | Tipo | Descripción |
|---|---|---|
| `Curp` | `string` | CURP validada de 18 caracteres. |
| `ApellidoPaterno` | `string` | Primer apellido del titular. |
| `ApellidoMaterno` | `string` | Segundo apellido del titular. |
| `Nombre` | `string` | Nombre(s) de pila. |
| `Sexo` | `string` | Género (`H` = Hombre, `M` = Mujer, `X` = No binario). |
| `FechaNacimiento` | `string` | Fecha de nacimiento en formato `DD/MM/AAAA`. |
| `Nacionalidad` | `string` | Clave de país de nacionalidad (ej. `MEX`). |
| `DocProbatorio` | `string` | Clave de documento probatorio (1: Acta de Nacimiento). |
| `AnioReg` | `string` | Año de registro en el Registro Civil. |
| `Foja` | `string` | Foja de registro del acta. |
| `Tomo` | `string` | Tomo del libro de actas. |
| `Libro` | `string` | Número de libro del acta. |
| `NumActa` | `string` | Número de acta de nacimiento. |
| `CRIP` | `string` | Clave del Registro de Identificación Personal (si existe). |
| `NumEntidadReg` | `string` | Código de dos dígitos del estado de registro. |
| `CveMunicipioReg` | `string` | Código del municipio de registro. |
| `NumRegExtranjeros` | `string` | Número de registro para personas extranjeras (si aplica). |
| `FolioCarta` | `string` | Folio de carta de naturalización (si aplica). |
| `CveEntidadEmisora` | `string` | Entidad federativa emisora de la CURP. |
| `StatusCurp` | `string` | Estatus de la clave (`AN`: Activa normal, etc.). |
| `Historicos` | `array` | Arreglo de CURPs históricas asociadas por modificación o unificación. |

---

#### Respuestas de Error

##### 400 Bad Request (CURP Inválida o Faltante)
```json
{
  "valid": false,
  "status": 400,
  "message": "La longitud de la CURP debe ser exactamente de 18 caracteres",
  "data": null,
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

##### 401 Unauthorized (Petición directa o Firma Inválida)
```json
{
  "valid": false,
  "status": 401,
  "message": "No autorizado: Cabeceras X-Idoo-Signature o X-Idoo-Timestamp ausentes (tráfico directo no permitido)",
  "data": null,
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

##### 404 Not Found (CURP no registrada)
```json
{
  "valid": false,
  "status": 404,
  "message": "CURP no encontrada o no registrada en RENAPO",
  "data": null,
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

##### 429 Too Many Requests (Límite de tasa excedido en idoo.dev)
Controlado directamente por el gateway de idoo.dev según el plan suscrito por el consumidor.

##### 503 Service Unavailable (Falla temporal con el proveedor)
```json
{
  "valid": false,
  "status": 503,
  "message": "Servicio de consulta no disponible temporalmente",
  "data": null,
  "timestamp": "2026-09-08T18:00:00-06:00"
}
```

---

### Tabla de Códigos de Estado HTTP

| Código | Significado | Causa y Solución |
|:---:|---|---|
| **`200`** | `OK` | Consulta exitosa. Se devuelven los datos completos de la CURP en el campo `data`. |
| **`400`** | `Bad Request` | Parámetro `curp` no enviado, longitud distinta de 18 caracteres o caracteres que no corresponden a la estructura de una CURP. |
| **`401`** | `Unauthorized` | Falta la API Key en idoo.dev, o se intentó llamar a la API directamente omitiendo el gateway y la firma HMAC. |
| **`403`** | `Forbidden` | La API Key de idoo.dev no tiene permisos para el recurso o la suscripción no está activa. |
| **`404`** | `Not Found` | La CURP proporcionada no existe o fue dada de baja en las bases de datos de RENAPO. |
| **`422`** | `Unprocessable Entity` | Formato sintáctico válido pero inconsistencia en las reglas de negocio (ej. entidad federativa inexistente o fecha fuera de rango). |
| **`429`** | `Too Many Requests` | Se excedió la cuota de peticiones por segundo o mensual asignada a tu plan en idoo.dev. Espera el intervalo o sube de plan. |
| **`502`** | `Bad Gateway` | El servicio central de RENAPO no respondió o devolvió un formato no interpretable. |
| **`503`** | `Service Unavailable` | Servicio externo en mantenimiento o saturado. Reintentar con retroceso exponencial (*exponential backoff*). |
