En producciónProductos y APIsIntegraciones

AcreditaLos datos oficiales del Perú, con su procedencia

API multi-tenant que resuelve RUC, tipo de cambio y ubigeo desde las fuentes oficiales peruanas —y la identidad, bajo contrato—, con el origen, la fecha y la licencia de cada dato dentro de la respuesta.

Busco algo como esto
acredita.stackealabs.com
Acredita: Sitio del producto
contribuyentes en el padrón, recargado cada madrugada
18.4 M
pruebas automáticas; la mitad vigila el cumplimiento
~2,170
sprints, cada decisión escrita en un ADR
47
de 2,452 peticiones respondidas durante el cambio de marca
2,452

Acredita se llamaba NexoID hasta octubre de 2026. Hoy es un producto de Stackea Labs.

Problema

Registrar un cliente en el Perú empieza por un RUC o un DNI. Y ahí empieza el problema: el dato existe —SUNAT publica su padrón como dato abierto— pero cada sistema que lo necesita acaba resolviéndolo a su manera. Un scraper contra la consulta web que se rompe cuando cambia el HTML. Una API de la que nadie sabe de dónde saca los datos ni de cuándo son. O el caso más común: alguien teclea el nombre de la empresa a mano.

Lo descubrí resolviendo lo mismo tres veces, en tres sistemas distintos. El dolor no era «falta una API de RUC»: era que ninguna respondía de dónde venía el dato ni de qué fecha era, y eso es exactamente lo que pregunta un auditor.

Contexto

Cuando un RUC entra en una ficha de cliente deja de ser una consulta y pasa a ser un registro. Si mañana alguien revisa por qué esa factura salió a nombre de esa empresa, la respuesta no puede ser «lo trajo una API». Tiene que ser «salió del padrón de SUNAT del 27 de septiembre, con esta licencia».

Con el DNI el problema cambia de naturaleza: ya no es un registro público, es la identidad de una persona. Quien la consulta por cuenta de otro es encargado de su tratamiento, con todo lo que eso exige. Tratar los dos datos igual es lo cómodo. Acredita nació para no hacerlo.

Arquitectura

API-first y headless. No hay panel para el cliente final: lo que se entrega es un contrato OpenAPI 3.1, un token y una respuesta con meta. Los tokens de prueba (acr_test_) no consumen cuota, y hay un sandbox público con datos sintéticos.

PiezaQué hace
Laravel 13 + Octane sobre FrankenPHPEl runtime: el framework vive en memoria entre peticiones
PostgreSQL 16El padrón completo, los tenants, la auditoría y la facturación
PgBouncerEn modo transaction para el tráfico de la API. La ingesta y las migraciones van por conexión directa, porque el ETL sostiene un advisory lock de sesión que PgBouncer perdería al repartir transacciones
Redis ×2Contadores, rate limit y caché, en dos instancias con políticas de persistencia distintas (ver Decisiones clave)
Ingesta nocturnaEl padrón se descarga cada madrugada; cada ficha guarda la fecha del archivo del que salió

Cada respuesta lleva su propia trazabilidad:

"meta": {
  "origen": "padron_reducido_sunat",
  "fecha_dato": "2026-09-27",
  "atribucion": "Padrón Reducido de Contribuyentes — SUNAT"
}

No es un campo decorativo: es lo que permite usar el dato en un documento fiscal.

Qué resuelve

Cuatro APIs públicas sobre un solo token, y una quinta bajo contrato:

  • RUC. La ficha del contribuyente —estado, condición, ubigeo y actividad económica— desde el padrón de SUNAT, y la búsqueda por razón social. 18.4 millones de contribuyentes, con el 82.6 % de las fichas resueltas hasta el nombre del distrito.
  • Tipo de cambio. El dólar y el euro oficiales del BCRP —con SUNAT de respaldo—: el de hoy, el de una fecha, el de un rango o el de un mes. No descuenta cuota.
  • Ubigeo. Departamento, provincia y distrito a partir de un código INEI.
  • Vigilancia de RUC. Un webhook firmado avisa cuando un RUC vigilado cambia de estado, de condición o de nombre. El cliente no tiene que preguntar: se le avisa.
  • Identidad (DNI), solo por contrato. Exige el scope dni.read, una finalidad declarada, una base legal y un anexo de tratamiento firmado. No se activa desde la web.

A eso se suman las dos cosas que vuelven integrable una API: lotes de hasta 100 documentos por petición e Idempotency-Key, para que una conexión cortada se repita sin consultar —ni cobrar— dos veces.

Decisiones clave

  • El dato se clasifica por su origen, y la clase manda. Clase A es dato público de fuente oficial: el padrón, el BCRP. Clase B es identidad de terceros que llega de un proveedor externo. Clase C, identidad de una fuente oficial contratada. Acredita es titular de su copia de la Clase A y solo encargado de tratamiento de la B y la C: no las retiene ni las usa para nada más.
  • Las dos instancias de Redis son un requisito de cumplimiento, no una optimización. La persistencia se configura por instancia, así que la del caché de Clase B corre sin disco (appendonly no, save ""). Una identidad de terceros no puede acabar escrita en disco ni por accidente. Consolidarlas ahorraría un contenedor y rompería la garantía.
  • El cumplimiento lo verifica el build. Persistir en PostgreSQL un DNI de Clase B o C lo rechaza una política de persistencia, y un test de arquitectura rompe el build si alguien lo intenta. Una regla legal que solo vive en un documento se olvida en el siguiente refactor.
  • El régimen lo decide el contenido, no la ruta. Un RUC que empieza en 10, 15 o 17 es una persona natural: GET /ruc/10… devuelve lo mismo que GET /dni/… y recibe el mismo trato. Sin el scope de identidad responde 403, la respuesta va private, no-store y la auditoría guarda el documento hasheado.
  • Sin caché de borde delante. Cada consulta llega al servidor y queda registrada antes de responder. Un CDN haría la API más rápida y la auditoría incompleta; gana la auditoría.
  • El error es parte del contrato. Código estable, mensaje en español y una señal de si se arregla esperando. Un 429 cuota_agotada es información; un 500 genérico es una llamada a soporte.

Lo que Acredita no hace es parte del diseño, no una lista de pendientes: no busca personas por nombre, no exporta personas naturales, no vende datos ni arma bases, y no puntúa ni perfila a nadie. En un dominio donde el dato es sensible, el alcance se define también por lo que se deja fuera.

Cómo se construye

Cuarenta y siete sprints, cada uno cerrado con un ADR que deja escrita la decisión y lo que costó. Unas 2,170 pruebas en Pest 4 —cerca de la mitad marcadas como de cumplimiento—, PHPStan en nivel 8 y una puerta de calidad local que corre antes de cada despliegue: si falla, no se despliega. Producción, además, se niega a arrancar si no pasa su propia verificación de invariantes, y un despliegue que falla se revierte solo. Va por la versión 1.32.

El cambio de marca —de NexoID a Acredita, con dominio, rutas y tokens nuevos— se hizo sin cortar el servicio: 2,452 de 2,452 peticiones respondieron bien durante el cambio.

No es disciplina por estética. En un servicio que trata identidad de terceros, la pregunta «¿por qué está hecho así?» la puede hacer un auditor, y la respuesta tiene que estar escrita antes de que llegue.

Lo nuevo

  • Un sandbox público con datos sintéticos y un token abierto, para probar sin pedir acceso.
  • Calendario: feriados, días hábiles, plazos y el cronograma de obligaciones de SUNAT. Gratis.
  • Validar a un proveedor en una sola llamada: si es agente de retención, si está en el régimen de buenos contribuyentes y si tiene inhabilitaciones en el OSCE.
  • SDKs de PHP y JavaScript descargables, un servidor MCP para usar la API desde asistentes de IA, colección de Postman y llms.txt.
  • Herramientas web gratis, como validar un RUC o consultar el cronograma de SUNAT, sin escribir código.

Aprendizajes

El producto nació de la peor forma posible de descubrir una necesidad: resolviéndola tres veces. Lo que no vi hasta la tercera fue que el valor no estaba en consultar el RUC —eso lo hace cualquiera— sino en poder demostrar de dónde salió.

La segunda lección fue sobre el DNI. Tratar un RUC 10 como «otro RUC» parece razonable hasta que te das cuenta de que su nombre es el nombre de alguien. Decidir el régimen por el contenido del dato, y no por el endpoint que lo pidió, es lo que cierra la puerta trasera: pedir por RUC lo que no se puede pedir por DNI.

Resultado

Acredita está en producción. Los dos sistemas que lo originaron —Podoplus y Diseña Estudio Dental— lo usan para validar RUC y DNI contra el padrón oficial desde septiembre de 2026, y el 9 de octubre llegó su primer cliente externo: una cadena de farmacias, con RUC y DNI bajo contrato. El primer cliente de Acredita fue el problema que lo creó; el segundo ya no fue mío.

3 capturas · toca una para verla en grande

Cuéntame qué quieres resolver. Te respondo en 24–48 h con una primera idea de cómo lo construiría, y si no soy la persona indicada, te lo digo.

Proyectos relacionados

En beta de SUNAT

Productos y APIs · Integraciones

Comprobia

Facturación electrónica SUNAT por API: tu sistema vende y Comprobia emite, firma, envía y reintenta.

Para: Sistemas que venden: puntos de venta, ERPs, ecommerce y apps

  • PHP 8.4
  • Laravel 13
  • PostgreSQL 16 + RLS
  • Redis 7
Ver el caso
Acceso anticipado

Productos y APIs · Integraciones

Avisa

Tu sistema reporta «cita creada» y Avisa decide qué mensaje de WhatsApp enviar, cuándo y cuánto cuesta.

Para: Clínicas y negocios que agendan, cobran y avisan por WhatsApp

  • PHP 8.4
  • Laravel 13
  • Octane + FrankenPHP
  • PostgreSQL 16
Ver el caso