API de RUC y DNI
Consulta un RUC o un DNI desde tu sistema y rellena los datos del cliente solo con el número. Devuelve razón social, estado, condición y domicilio fiscal para RUC; nombres y apellidos para DNI.
1. Empezar
Son tres pasos:
- Pides tus credenciales. Te llegan una API Key y un API Secret.
- Pruebas con una llave de sandbox, gratis y con un tope de consultas al mes.
- Cambias las credenciales por las de producción y ya estás consultando de verdad.
Dirección base
https://cismafact.alwaysdata.net/api
La misma que para emitir. Las consultas cuelgan de
/consultas:
/consultas/ruc/{numero},
/consultas/dni/{numero} y
/consultas/cuota.
Todas son GET y responden en JSON.
2. Credenciales
Van en las cabeceras de cada petición. Las dos son obligatorias.
X-Api-Key: tu_api_key
X-Api-Secret: tu_api_secret
Accept: application/json
El API Secret se enseña una sola vez.
Guárdalo en cuanto lo recibas. No lo pongas en el código de una página web ni en una aplicación de móvil: cualquiera puede leerlo de ahí y gastar tu cuota. Va en tu servidor. Si se te pierde o crees que alguien más lo tiene, pide que te lo cambien.
3. Pruebas
Te damos una llave de sandbox gratuita para que dejes tu integración terminada antes de contratar nada. Consulta los mismos datos reales que producción —la misma SUNAT y el mismo RENIEC—, porque con datos inventados no verías si el servicio te sirve.
Pruébala con RUC y DNI de verdad: los tuyos, los de tus clientes, los que quieras comprobar. No hay números especiales que devuelvan casos preparados.
Lo único distinto de producción es el tope.
La llave de sandbox trae 20 consultas de cada tipo al mes: 20 de RUC
y 20 de DNI, que se cuentan por separado. Al agotarse responde
429. Puedes ver lo que te queda en
cualquier momento con GET /api/consultas/cuota,
y si necesitas más para terminar, nos lo dices.
Cuando la consulta no sale adelante responde
422 y el porqué viene en
message, así que conviene leerlo
y no solo mirar el código: es el mismo 422 para un número mal escrito
(prueba 20000000000, cuyo dígito
verificador no cuadra, o un DNI de 7 cifras) que para uno correcto cuyo titular
no aparece.
Cuando termines, cambias las dos cabeceras por las de producción. No hay que tocar nada más.
4. Consultar RUC
El número y los datos de este ejemplo son inventados, solo para enseñar la forma de la respuesta. Al probar verás los datos reales del RUC que consultes.
GET https://cismafact.alwaysdata.net/api/consultas/ruc/20000000001
Respuesta
{
"success": true,
"data": {
"valido": true,
"numero": "20000000001",
"tipo": "ruc",
"nombre": "EMPRESA DE EJEMPLO S.A.C.",
"estado": "ACTIVO",
"condicion": "HABIDO",
"direccion": "AV. DE PRUEBA NRO. 100",
"ubigeo": "150101",
"departamento": "LIMA",
"provincia": "LIMA",
"distrito": "LIMA",
"fuente": "consultado antes"
},
"message": null
}
| Campo | Qué es |
|---|---|
| nombre | Razón social o nombre del contribuyente. |
| estado | ACTIVO, BAJA DE OFICIO, SUSPENSION TEMPORAL… Si no está activo, no puede emitir comprobantes. |
| condicion | HABIDO o NO HABIDO. No habido significa que SUNAT no lo encontró en su domicilio. |
| direccion | Domicilio fiscal. |
| ubigeo | Código de 6 dígitos de departamento, provincia y distrito. |
| fuente | De dónde salió el dato: proveedor, padron, consultado antes o ninguna. Con ninguna vienen solo el número y el tipo, sin ficha. |
Un 200 no siempre trae la ficha
Si el número es correcto pero no se pudo consultar en ese momento, la respuesta
sigue siendo 200 con
success: true, porque el número
vale y no queremos bloquearte por un proveedor caído. Pero llega
"fuente": "ninguna", un
message explicándolo, y
sin nombre ni
direccion.
Comprueba que el campo existe antes de usarlo, en vez de fiarte solo de
success.
5. Consultar DNI
GET https://cismafact.alwaysdata.net/api/consultas/dni/12345678
Respuesta
{
"success": true,
"data": {
"valido": true,
"numero": "12345678",
"tipo": "dni",
"nombre": "JUAN DE PRUEBA EJEMPLO",
"nombres": "JUAN",
"apellido_paterno": "DE PRUEBA",
"apellido_materno": "EJEMPLO",
"fuente": "consultado antes"
},
"message": null
}
Tienes el nombre completo ya armado en nombre y también
por partes, por si tu sistema guarda los apellidos en campos separados.
6. Ver tu cuota
Cuánto llevas gastado y cuánto te queda. No gasta cuota.
GET https://cismafact.alwaysdata.net/api/consultas/cuota
{
"llave": "Producción",
"entorno": "produccion",
"plan": "Pro",
"expira_en": null,
"renueva": "2026-10-01",
"servicios": [
{ "servicio": "ruc", "nombre": "Consulta RUC", "disponible": true,
"limite_mensual": 10000, "usadas": 1, "restantes": 9999 },
{ "servicio": "dni", "nombre": "Consulta DNI", "disponible": true,
"limite_mensual": 2000, "usadas": 1, "restantes": 1999 }
]
}
Los límites del ejemplo son ilustrativos: los tuyos son los de tu plan, y salen aquí.
7. Errores
Cuando algo va mal, success es
false y
message explica qué pasó, en castellano.
Puedes enseñárselo a tu usuario tal cual.
| Código | Qué pasó | Qué hacer |
|---|---|---|
| 401 | Faltan las cabeceras o las credenciales no valen. | Revisa que mandas las dos y que no llevan espacios de más. |
| 403 | La llave está bloqueada, venció, o tu plan no incluye ese servicio. | El mensaje dice cuál de los tres. Escríbenos. |
| 422 | El número no es válido: no tiene los dígitos que toca, o el dígito verificador no cuadra. | Nada: no gasta cuota. Enséñale el mensaje a tu usuario. |
| 429 | Se acabó tu cuota del mes, o vas demasiado rápido. | Espera al día 1, sube de plan, o baja el ritmo. |
| 503 | Ese servicio está fuera de servicio un rato. | Reintenta en unos minutos. No gasta cuota. |
Ejemplo
{
"success": false,
"data": null,
"message": "El RUC no es válido: el dígito verificador no cuadra."
}
8. Límites
- 30 peticiones por minuto. Es aparte de tu cuota mensual: evita que te la gastes de golpe por un fallo en tu código.
- Cuota mensual según tu plan, contada por separado para RUC y para DNI.
- Lo que falla no gasta cuota. Un número mal escrito o un servicio caído no te cuestan nada.
- La cuota se reinicia el día 1 de cada mes. No se acumula lo que no gastaste.
9. Ejemplos
curl
curl -H "X-Api-Key: tu_api_key" \
-H "X-Api-Secret: tu_api_secret" \
-H "Accept: application/json" \
https://cismafact.alwaysdata.net/api/consultas/ruc/20000000001
PHP
<?php
function consultarRuc(string $ruc): ?array
{
$ch = curl_init('https://cismafact.alwaysdata.net/api/consultas/ruc/' . $ruc);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . getenv('CISMA_API_KEY'),
'X-Api-Secret: ' . getenv('CISMA_API_SECRET'),
'Accept: application/json',
],
]);
$cuerpo = json_decode(curl_exec($ch), true);
curl_close($ch);
// Un RUC que no existe no es un fallo del programa: devuelve null y que
// el formulario avise, en vez de reventar.
return ($cuerpo['success'] ?? false) ? $cuerpo['data'] : null;
}
$empresa = consultarRuc('20000000001');
echo $empresa['nombre'] ?? 'No encontrado';
Python
import os, requests
CABECERAS = {
"X-Api-Key": os.environ["CISMA_API_KEY"],
"X-Api-Secret": os.environ["CISMA_API_SECRET"],
"Accept": "application/json",
}
def consultar_ruc(ruc):
r = requests.get(f"https://cismafact.alwaysdata.net/api/consultas/ruc/{ruc}",
headers=CABECERAS, timeout=15)
cuerpo = r.json()
return cuerpo["data"] if cuerpo.get("success") else None
empresa = consultar_ruc("20000000001")
print(empresa["nombre"] if empresa else "No encontrado")
JavaScript / Node.js
// Desde el servidor, nunca desde el navegador: ahi el secreto queda a la vista.
const cabeceras = {
'X-Api-Key': process.env.CISMA_API_KEY,
'X-Api-Secret': process.env.CISMA_API_SECRET,
'Accept': 'application/json',
};
async function consultarRuc(ruc) {
const r = await fetch(`https://cismafact.alwaysdata.net/api/consultas/ruc/${ruc}`, { headers: cabeceras });
const cuerpo = await r.json();
return cuerpo.success ? cuerpo.data : null;
}
const empresa = await consultarRuc('20000000001');
console.log(empresa?.nombre ?? 'No encontrado');
¿Lo quieres probar?
Escríbenos y te damos credenciales de prueba para que dejes tu integración lista antes de contratar nada.