Qué cambia, y cuándo
Cambios de la API de NexoID
Lo que cambia para quien integra, versión a versión. No es la bitácora de operación
—esa vive en docs/operacion/bitacora.md y es interna— ni el registro de decisiones,
que son los ADR.
🔒 Política de cambios (§15.7). Un cambio aditivo —un campo nuevo en una
respuesta, un endpoint nuevo, un valor nuevo en un enum— no sube la versión mayor y
puede llegar cualquier día: tu integración tiene que ignorar lo que no conoce. Un
cambio incompatible abriría /v2, y /v1 seguiría sirviendo doce meses. Hoy no
existe /v2 ni está previsto.
1.29.1 · 2026-10-13
- Sin cambios en la API. Corrige dos textos de operación: el registro de tratamiento, que tras encender la consulta externa seguía diciendo en su plazo de conservación que estaba retirada, y un aviso de «credencial caducada» que la consola daba sin motivo al encenderla.
1.29.0 · 2026-10-13
- La consulta externa de DNI vuelve, para las cuentas que la tienen contratada. Un DNI que no está en el padrón de la
SUNAT se consulta otra vez al proveedor externo (apiperu.dev) y responde
200conmeta.origen = apiperu_dev. Sin la consulta externa contratada, sigue siendo404 no_esta_en_padron_y_fallback_no_habilitado./medice si tu token la tiene (fallback.permitido). - Textos legales, versión 2026-10-13: la política de privacidad, los términos y el anexo de tratamiento vuelven a nombrar al proveedor de consulta externa y a decir que lo que devuelve se guarda solo en memoria, 48 horas como máximo.
1.28.0 · 2026-10-10
- La consulta externa de DNI está apagada. Un DNI que no está en el padrón de la SUNAT responde
404conmeta.motivo = no_esta_en_padron_y_fallback_no_habilitado, sin reintento: NexoID ya no consulta a proveedores externos./medicefallback.permitido: falsey/health,fallback_externo: no_configurado. - El match no da pistas: con
no_coincide,data.gradoesnull. Solocoincidelleva el grado. - Textos legales, versión 2026-10-10: la política de privacidad, los términos y el anexo de tratamiento recogen el doble papel de NexoID (responsable de su copia del padrón y de lo que comunica desde ella), retiran al proveedor externo, añaden la información de una bolsa antes de pagar y la cláusula de validación de comprobantes, y fijan el domicilio en Jr. Argentina 371.
1.27.0 · 2026-10-09
- Errores de la petición que eran un 500, ahora son 422
documento_invalido: una fecha con buen formato que no existe en el tipo de cambio (/tipo-cambio/2026-02-30), un lote cuyosdocumentosno son texto, yq[]en/ruc/buscar. /ruc/buscarbusca el texto literal:%y_ya no son comodines, y la búsqueda necesita al menos 3 letras o números y admite 100 caracteres./vencimientos/proximosresponde 404anio_no_disponiblesidesdecae después del último año del cronograma, en vez de una lista vacía: «no lo sé» no es «no vence nada».- Repetir un lote con la misma
Idempotency-Keysigue sin cobrarse, y ahora queda registrado como consulta no facturable de quien la repitió. - Vigilancia: como mucho 10 endpoints de webhook por cliente y URLs de 2,048 caracteres (
tope_watch_alcanzadoydocumento_invalido, los dos 422), y la prueba de un endpoint espera 3 s y admite 6 por minuto. Un nombre de lista repetido es un 422 con su mensaje. - El presupuesto de fallback cuenta cada llamada al proveedor de DNI, también las que no encuentran a nadie, que es lo que cuesta.
- La demo de la web tiene un tope diario de todas las consultas juntas, además del de cada IP.
1.26.0 · 2026-10-08
- Casos de uso en la web:
/casos/y cuatro páginas —facturación y ERP, ecommerce, estudios contables y CRM—, cada una con el problema, una petición que corre tal cual con el token público del sandbox y la bolsa que encaja. - La web carga más estable en móvil: el fondo del inicio ya no se desplaza cuando carga la fuente.
- La API no cambia. Ninguna ruta, campo ni error nuevo: el contrato sube de versión con el servicio.
1.25.1 · 2026-10-08
- Los padrones de SUNAT nunca vuelven a una lista más vieja que la cargada. SUNAT no sirve el mismo archivo desde
todos sus nodos: la relación de buenos contribuyentes llegaba con fecha 2023-01-26 a nuestro servidor y con 2025-07-10 a
otros. Sin esta guarda, la lista habría oscilado según el nodo y la vigilancia de RUC habría avisado de cambios que no
ocurrieron. La fecha de cada lista sigue en
meta.fecha_padrones.
1.25.0 · 2026-10-08
-
Los padrones de SUNAT en la ficha de RUC.
es_agente_retencionyes_buen_contribuyentedejan de ser siemprenull: salen del padrón de agentes de retención y de la relación de buenos contribuyentes que publica SUNAT, ymeta.fecha_padronesdice de qué fecha es cada lista. Siguen ennullmientras una lista no esté aplicada: no lo sabemos, que no es «no».es_agente_percepcion,obligado_pleyafiliado_seesiguen sin fuente. -
Los eventos
ruc.agente_retencion_cambiadoyruc.buen_contribuyente_cambiadoya se disparan: llevaban declarados sin fuente desde la primera versión de Watch. SUNAT actualiza esas listas unas pocas veces al año. -
GET /proveedor/{ruc}, el alta de proveedor: en una consulta,- la ficha;
- los dos padrones con su fecha;
- las inhabilitaciones vigentes para contratar con el Estado, del OSCE (hoy OECE);
- si ya la vigilas;
- avisos: no activa, no habida, sancionada.
Cuesta una consulta, como la ficha. Solo RUC
20: un10,15o17es 422 sin cobrarse.sancionesesnullsi la lista no está cargada. -
Los SDKs
0.9.0traenproveedor(). El servidor MCP0.3.0, la herramientaconsultar_proveedor, que rechaza un RUC de persona sin llamar.
1.24.0 · 2026-10-08
- El calendario del Perú, gratis. Tres rutas nuevas, sin scope y sin descontar consultas, como el ubigeo:
GET /calendario/feriados/{anio}: los 16 feriados nacionales del año —Jueves y Viernes Santo incluidos— con su nombre y su norma. Con?sector=publico, también los días no laborables que decreta el Ejecutivo, con su decreto supremo.GET /calendario/{fecha}: si un día es hábil, por qué no y los hábiles anterior y siguiente.GET /calendario/plazo?desde=…&dias=…: en qué fecha vence un plazo de N días hábiles, contado desde el día siguiente, y qué días se saltó.
- El cronograma de vencimientos de SUNAT, gratis. Las obligaciones mensuales (IGV, renta, retenciones, percepciones e
ITF) según la RS 281-2022/SUNAT:
GET /vencimientos/{anio}: los 12 periodos, con la fecha de cada último dígito del RUC y la de los buenos contribuyentes.estado: publicadoes la tabla de SUNAT;calculado, la regla aplicada a un año que SUNAT aún no publica, conaviso.GET /vencimientos/proximos?digito=N: lo próximo que vence para un dígito, con los días que faltan. 🔒 Pide el último dígito, nunca el RUC: un?ruc=responde 422.
- Las cinco responden con
meta.origennormas_feriadososunat_cronogramaymeta.cubre, los años que cubren. Un año fuera de ellos es 404anio_no_disponible, nunca una lista vacía. Responden también al token público del sandbox. GET /demo/tipo-cambio, sin token: el tipo de cambio del día para el conversor de la landing. 10 por minuto y 50 al día por IP, aparte de la demo de RUC.- El contrato declara el 422 de las rutas que solo validan su query (
/ruc/buscar,/tipo-cambio/rangoy las nuevas). - Los SDKs
0.8.0traenferiados(),dia(),plazo(),vencimientos()yproximosVencimientos(), que con un RUC envía solo su último dígito. El servidor MCP0.2.0, tres herramientas:feriados,plazo_habilyvencimientos_sunat.
1.23.0 · 2026-10-08
- El sandbox. Un token de prueba (
nxid_test_) responde ahora con un conjunto fijo y sintético de documentos, nunca con el padrón real: siete empresas —una por caso: activa, sin ubigeo, de baja de oficio, no habida, suspendida, importadora e industrial—, la persona sintética99999999y un RUC válido que da 404. Las respuestas llevanmeta.origen: sandboxy no cambian, así que sirven para tu CI. La lista, en/docs/sandbox. 🚩 Si usabas un token de prueba contra RUC reales, ahora reciben 404: para datos reales, un tokenlive. - El token público del sandbox, publicado en
/docs/sandbox: tu primera consulta sin pedir nada. Soloruc.readyruc.search, 30 consultas por minuto y 500 al día por IP. X-Nexoid-Simular: 429o503, solo con un token de prueba: devuelve el error de verdad —rate_limit_excedidoconRetry-After, oservicio_no_disponible— para probar cómo reacciona tu sistema.no_disponible_en_sandbox(403), un código nuevo: Watch y la validez de comprobantes, con un token de prueba. Usan datos reales. Los SDKs0.7.0lo conocen./medice si el token responde con el sandbox (token.sandbox)./docs/sdks: los SDKs de PHP y JavaScript y el servidor MCP, para bajar./docs/postman.json: la colección, con el token público ya puesto. Y el inicio rápido reescrito: curl, PHP, JavaScript y Python con el sandbox.- Los textos legales, en la versión 2026-10-08: la política de privacidad (§10) describe cómo se cuentan las visitas de la web pública, de forma agregada y sin cookies ni ningún identificador. Los términos y el anexo no cambian.
1.22.0 · 2026-10-07
GET /demo/ruc/{ruc}, la demo de la landing: un RUC20sin token, para ver la ficha antes de pedir acceso. Un RUC de persona natural responde 403, como siempre. Admite 10 consultas por minuto y 50 al día por IP, y no se cobra. Para integrar, pide un token: la demo no es una forma de consultar en producción.- Los tokens de prueba (
nxid_test_) caducan: a los 30 días si no se pide fecha, y como mucho a los 90. Y admiten 500 consultas al día; la siguiente responde 429 con el código nuevotope_de_pruebas_alcanzado, no reintentable: se reinicia a medianoche, hora de Lima. Siguen sin consumir tu cuota ni cobrarse. Los SDKs0.6.0conocen el código.
1.21.0 · 2026-10-06
GET /health?estricto=1responde 503 también cuando el servicio estádegraded, con el mismo cuerpo. Es para un monitor de uptime que solo mira el código HTTP. Sin el parámetro,/healthno cambia:degradedsigue en 200.- Cinco códigos de error nuevos en el catálogo, para dos capacidades que llegan cerradas —todavía no se publican ni se
venden—:
intentos_agotados(429),servicio_no_disponible(503),credencial_sol_no_configurada(422),credencial_sol_rechazada(422) yfuente_no_disponible(503).servicio_no_disponibleyfuente_no_disponibleson reintentables. Los SDKs0.5.0los conocen. /docs/asistentes: cómo integrar NexoID con un asistente de código, y un servidor MCP de datos públicos —sin DNI— para que el asistente consulte empresas, el tipo de cambio y el ubigeo mientras trabaja.
1.20.0 · 2026-10-06
- Precios nuevos, al precio del mercado. Bolsas de 12 meses con IGV incluido: Micro, S/ 19 por 50,000 consultas; Inicial, S/ 59 por 250,000; Crecimiento, S/ 149 por 1,000,000; y Empresa, S/ 399 por 5,000,000. La vigilancia de RUC va incluida desde Crecimiento, con 500 RUC, y en Empresa con 5,000. El plan gratis sigue en 1,000 consultas al mes.
- Los términos, en la versión 2026-10-06: la cláusula 9 describe las bolsas prepago, y la 6 dice qué no consume cuota.
- La API pública no cambia: el contrato solo sube de versión.
1.19.0 · 2026-10-06
- La app de NexoID para HubSpot vigila cambios en SUNAT, todavía en preparación. Con «Vigilar cambios en SUNAT»
encendido, cada empresa que actualizas queda vigilada, y si SUNAT cambia su estado, su condición o su razón social, la
empresa se actualiza sola en HubSpot, con el último cambio y su fecha para tus workflows. No consume cuota: ocupa una
lista de Watch de tu plan, y pide un token con
watch.manage. Solo empresas (RUC 20). - La API pública no cambia: el contrato solo sube de versión.
1.18.0 · 2026-10-06
- La app de NexoID para HubSpot, en preparación. Una tarjeta en la ficha de cada empresa consulta SUNAT por su RUC y
guarda los datos en propiedades
nexoid_*, y los ajustes de la app actualizan hasta 100 empresas de una vez. Solo empresas (RUC 20): nunca datos de personas naturales. Usa un token tuyo de NexoID, que se vincula una vez, y consume tu cuota como la API. Todavía no está abierta: la instalamos nosotros, cuenta por cuenta. - La API pública no cambia: el contrato solo sube de versión.
1.17.0 · 2026-10-06
- El tipo de cambio es gratis. No descuenta de tu cuota del mes ni de tu bolsa, y responde aunque las hayas agotado.
Sigue pidiendo un token con
tc.read—el del plan gratis lo tiene— y lleva el límite de peticiones por minuto de tu plan. En el contrato,x-consume-cuotapasa afalseen sus operaciones. - El euro. Añade
?moneda=EURa/tipo-cambio,/tipo-cambio/{fecha}o/tipo-cambio/rango: es el que publica el BCRP en soles por euro, con su histórico. Sin el parámetro, el dólar de siempre. Cada cotización traemoneda, y el euro llega conorigen: "bcrp", un valor nuevo del enum: si lo validas contra una lista cerrada, añádelo. El euro no tiene respaldo de SUNAT: si el BCRP no publica, se sirve el último ymeta.antiguedad_diaslo dice. /tipo-cambio/mes/{AAAA-MM}: las cotizaciones publicadas de un mes, con la respuesta derango.nro_trabajadoresen la ficha de RUC: cuántos trabajadores declaró, del padrón extendido. Un entero;0es que declaró cero ynullque SUNAT no lo trae, que es lo normal: llega en el 3.3 % de las fichas.reintentableen cada error (error.reintentable) y en el 404 de RUC y DNI (meta.reintentable):truesi se arregla esperando —hoy,rate_limit_excedidoy el 404 degradado—. Confalse, reintentar repite el mismo error. El 429 del limitador declaraRetry-Afteren el contrato.- Los SDKs
0.4.0:tipoCambioMes(), el parámetromoneda,nroTrabajadoresen PHP yesReintentable()en los errores.
1.16.0 · 2026-10-05
comercio_exterioren la ficha de RUC. Si el contribuyente importa, exporta o las dos cosas, como lo escribe SUNAT en el padrón extendido: «IMPORTADOR», «EXPORTADOR», «IMPORTADOR/EXPORTADOR» o «SIN ACTIVIDAD». Está en el 72.7 % de las fichas, y su fecha esmeta.fecha_dato_extendido. No es una lista cerrada: si SUNAT añade un valor, llega tal cual. Es un campo aditivo: tu integración tiene que ignorar lo que no conoce.- Documentación nueva: un inicio rápido, la referencia por operación y
el catálogo de errores en su propia página. Cada página tiene su versión en Markdown (
/docs.md,/docs/referencia.md…), y/llms.txtlas enumera para que un asistente de IA integre a la primera. - En el panel de tu cuenta,
/cuenta: tu facturación —tus bolsas con su saldo y lo que costaron, y tus facturas con sus pagos— y tu configuración: tu nombre, tu contraseña, tu segundo factor y los datos con los que te facturamos. - Los SDKs
0.3.0leencomercio_exterior.
1.15.0 · 2026-10-04
El tipo de cambio dice de dónde viene cada cotización. Desde el 3 de octubre el BCRP no responde a las consultas automatizadas. Mientras dure, la cotización del día sale de la SUNAT, que publica el mismo tipo de cambio de la SBS.
origenen cada cotización (data.origen, ydata[].origenen/tipo-cambio/rango):bcrp_sbsosunat_sbs.meta.origenymeta.atribucionson los de la cotización que recibes; en un rango,meta.origenes el de la más reciente y la atribución nombra a todas las fuentes que aparecen.sunat_sbses un valor nuevo del enumorigen. Si tu integración lo valida contra una lista cerrada, añádelo.- Los números no cambian de significado: compra y venta del cierre SBS del día de
fecha. SUNAT publica con tres decimales. Cuando el BCRP vuelva, sus cotizaciones sustituyen a las de SUNAT para las mismas fechas. /healthdice enfuentes.tipo_cambio.origende quién es la última cotización.
1.14.0 · 2026-10-04
Sin cambios en la API. Dos cosas nuevas en el panel de tu cuenta, /cuenta:
- Tus tokens, desde tu cuenta. Emítelos con los permisos que incluye tu plan, rótalos con unas horas de margen para
cambiarlos sin cortar, revócalos y limita desde qué IPs se usan. El token se ve una sola vez, al emitirlo. Los permisos
de DNI (
dni.read,dni.fallback) solo aparecen si tu cuenta tiene firmado el anexo de datos; si no, pídelo. Hasta 10 tokens vigentes. - Consulta en línea. Un RUC o un DNI, de uno en uno, con los mismos permisos y la misma cuota que la API: antes de consultar ves de qué se descontará, y si no se encuentra no se cobra. No pregunta a proveedores externos: un DNI que no esté en el padrón sale como no encontrado. Hasta 10 consultas por minuto y 200 al día por persona.
1.13.0 · 2026-10-03
Sin cambios en la API. Dos cosas alrededor de ella:
- El panel de tu cuenta, en
/cuenta. Ves tu plan, las consultas que llevas este mes y cuándo vuelve a empezar la cuota, el saldo de tus bolsas, tus tokens —solo el prefijo— y tus consultas de los últimos 30 días, encontradas y no encontradas. Se entra con la invitación que te enviamos, una contraseña y un segundo factor obligatorio. No muestra qué documentos consultaste. Se activa cuenta por cuenta: si no tienes invitación, todavía no está abierto para ti. - Desplegar ya no corta ni deja peticiones esperando, también las de lote (
POST).1.12.1lo traía a medias y solo llegó al entorno de pruebas.
1.12.1 · 2026-10-03
Sin cambios en la API. Desplegar una versión nueva ya no deja peticiones esperando: la nueva arranca junto a la anterior y la sustituye cuando está lista. Hasta ahora, una consulta que llegaba justo en el cambio podía tardar hasta 15 s o quedarse sin respuesta.
1.12.0 · 2026-10-03
Nuevo, y aditivo: la cuota del mes en cada respuesta.
- Toda respuesta autenticada trae, junto a las
RateLimit-*:X-Cuota-Limite, las consultas del mes de tu plan;X-Cuota-Restante, lo que queda, ya descontada esa consulta (y los N de un lote);X-Cuota-Reinicio, el primer día del mes siguiente a medianoche de Lima;X-Cuota-Bolsa, lo que queda en tus bolsas prepago, si tienes saldo.
- Un restante en 0 no corta mientras quede bolsa o tu plan admita excedente.
- Si no llegan, el contador no respondió: no es «sin cuota». Un token
testno las lleva, porque no consume. - El contrato las declara en
components.headers. - Los SDKs
0.2.0las leen:ultimaCuota()en PHP yultimaCuotaen JS.
1.11.1 · 2026-10-03
Sin cambios en la API. El padrón del 2026-10-03 no se publicó: el archivo de la SUNAT traía un RUC repetido y la carga
se detuvo. Hasta que se publique de nuevo, la API sirve el del 2026-10-02 con su fecha_dato. Ahora un RUC repetido se
publica una vez, con su fila activa.
1.11.0 · 2026-09-27
Nuevo, y aditivo: las bolsas prepago.
/mey/usotraenbolsas:saldo(lo que te queda, sumando todas),vence_primeroyactivas, con el paquete, las consultas, las consumidas y el vencimiento de cada una.- El orden al consumir: primero la cuota del mes de tu plan, después la bolsa que vence antes, y si no queda nada,
429 cuota_agotada, como hasta ahora. - Lo que no se cobra tampoco se descuenta de la bolsa: los 404, los tokens
testy las repeticiones con la mismaIdempotency-Key. - Sin bolsas,
bolsas.saldoes 0 y nada más cambia.
1.10.1 · 2026-09-27
Sin cambios en la API.
- Precios: incluyen el IGV. Los términos de servicio pasan a la versión 2026-09-27, y solo cambia esa frase de §9.
- Navegación: la documentación, el estado y los textos legales enlazan de vuelta al inicio y a los precios.
- Páginas nuevas: una página que no existe te devuelve al inicio;
/apis/lista las cuatro APIs; y hay/sitemap.xml.
1.10.0 · 2026-09-27
Sin cambios en la API. https://nexoid.victorllerena.com/ sirve ahora la página del producto: qué ofrece cada API,
los precios y cómo empezar. La documentación sigue en /docs, el estado en /estado y la API en /id/v1. El plan
gratuito pasa de 500 a 1,000 consultas al mes.
1.9.7 · 2026-09-26
Sin cambios en la API. Los ejemplos de la documentación —el portal, las guías, el contrato y la colección de
Postman— usan ahora el DNI del titular del servicio (72492353, RUC 10724923530) y el sintético 99999999, en vez de un
documento que no le pertenecía. El ejemplo de la ficha de DNI del contrato trae además su RUC con el dígito verificador
correcto: 10999999994. Si copiaste alguno de los ejemplos anteriores en tus tests, sustitúyelo por estos.
1.9.6 · 2026-09-26
Sin cambios en la API. Si una petición se queda sin respuesta durante un despliegue, ahora falla en segundos en vez
de esperar hasta el timeout de tu cliente: a los 15 s, un GET se reintenta contra la instancia nueva y un POST
recibe un 504. Un 504 en un POST /ruc/batch o /dni/batch significa que el lote pudo llegar a procesarse; repítelo
con la misma Idempotency-Key para no consultar dos veces. Ninguna consulta legítima de la API se acerca a ese límite:
la más lenta medida en producción tardó 4.7 s.
1.9.5 · 2026-09-25
Sin cambios en la API. Un despliegue ya no deja caer peticiones con cuerpo: antes, un POST /ruc/batch o
POST /dni/batch que llegara justo cuando se retiraba la instancia saliente podía recibir un 502, porque esa instancia
a veces no terminaba de apagarse y lo que le entraba no lo contestaba nadie. Ahora se la saca de la circulación antes
de pararla, y tu petición espera los segundos del cambio en vez de fallar. Esto corrige lo que decía la nota de 1.9.3.
1.9.4 · 2026-09-24
Sin cambios en la API. Cambios internos de operación: los avisos de latencia que genera un despliegue salen con menos severidad y lo dicen, y hay un informe de los objetivos de latencia con su muestra.
1.9.3 · 2026-09-24
Sin cambios en la API. Un despliegue retiene menos tiempo tus peticiones: la instancia saliente tiene 2 s para pararse, en vez de 10. Si una consulta de DNI que sale al proveedor externo sigue en curso justo en ese momento, puede recibir un 502; se reintenta sin más.
1.9.2 · 2026-09-24
El contrato OpenAPI dice por fin lo que la API devuelve, en las 21 operaciones. Hasta hoy solo se contrastaban
las fichas de RUC y DNI con respuestas reales; el resto se escribió a mano y había envejecido. Las respuestas no
cambian —salvo una, abajo—: cambia su descripción. Si generaste tipos desde /openapi.json, regenéralos.
| Dónde | El contrato decía | Lo que se devuelve, y ahora se declara |
|---|---|---|
WatchLista |
rucs, creado_en |
vigilados |
WatchEvento |
tipo, valor_antes, valor_despues |
evento, campo, antes, despues, fecha_dato |
POST /watch/listas y POST /watch/webhooks |
200 | 201 |
/me, /uso y Watch |
meta con origen obligatorio |
meta con solo request_id (MetaDeRespuesta) |
/ruc/buscar |
sin resumen, cuatro campos y un parámetro limite |
resumen, los campos de ubicación, y sin limite: el servicio siempre devolvió como mucho 20 y lo ignoraba |
/tipo-cambio/rango |
sin resumen |
resumen.dias y resumen.limite |
/tipo-cambio |
— | meta.fecha_solicitada, meta.antiguedad_dias y meta.aviso |
/health |
hora, dependencias sin forma |
fuentes con su umbral y dependencias campo a campo |
/me, /uso, agregar y quitar RUC, probar un webhook |
objetos sin propiedades | cada campo declarado |
El único cambio en una respuesta: /uso → consultas.por_servicio es un mapa servicio → consultas, y cuando
estaba vacío salía como lista ([]). Ahora sale como objeto ({}). Si lo recorrías como lista, léelo como mapa.
1.9.1 · 2026-09-24
Un campo más en /health, aditivo. fuentes.padron_extendido aparece ahora siempre —también como
sin_datos si nunca se cargó— y trae su umbral_h: 840 horas, 35 días. Pasado ese plazo sale como
degradado. Como el tipo de cambio, informa y no cambia estado: el padrón extendido es mensual y de un
tercero, y sin él la API sigue resolviendo; lo que envejece es el ubigeo y la ficha ampliada.
Si tu monitor mira solo estado, no notas nada. Si recorre fuentes, ahora hay una más con umbral.
1.9.0 · 2026-09-23
🚩 Un código de error nuevo en Watch, y un despliegue que ya no te corta.
- Los topes de vigilancia tienen su propio código:
tope_watch_alcanzado. Crear una lista de más, o pasar del número de RUC que permite tu plan, devolvía422 documento_invalido—y el documento estaba perfecto—. Sigue siendo un 422 y el mensaje sigue diciendo cuántos hay y cuántos permite el plan; lo que cambia es elcodigo. Si tu integración ramifica pordocumento_invalidoenPOST /watch/listasoPOST /watch/listas/{id}/rucs, añade el nuevo: es el único que se arregla subiendo de plan y no revisando el documento. Está en el catálogo de/docsy en el contrato. - Desplegar ya no deja la API sin servicio. Hasta ahora, cada actualización devolvía
502durante unos 8 s mientras se reemplazaba el contenedor de la aplicación. Ahora el puerto lo publica un frente que no se reemplaza, y las peticiones esperan a que la aplicación vuelva: medido, una consulta en mitad de un despliegue tarda unos segundos y responde200. Si tu cliente tiene un tiempo de espera muy corto —menos de 10 s— puede que veas una lentitud ocasional donde antes veías un error.
Nada más cambia: las 21 operaciones, sus respuestas y el resto de los códigos son los mismos.
1.8.0 · 2026-09-21
🚩 Dos cambios en la entrega de webhooks de Watch. Ninguno cambia un endpoint ni una respuesta de la API, pero pueden alcanzar a tu receptor:
- Las redirecciones ya no se siguen. Si tu URL responde
301,302,307o308, la entrega cuenta como fallida —con esehttp_status— y se reintenta según el calendario de siempre. Responde2xxen la URL que registraste; si la cambiaste, registra la nueva. Antes se seguían hasta cinco saltos, incluso haciahttp. - Una URL que resuelve a una dirección interna no recibe nada: privadas, de bucle local,
de enlace local o multicast, en IPv4 o IPv6. La entrega cuenta como fallida y en su
respuestadicedestino_no_permitidocon la dirección; la prueba de integración (POST /watch/webhooks/{id}/probar) devuelveenviado: falsecon el mismo motivo. Un receptor público no nota nada.
Si tu receptor sigue una de las dos cosas de arriba, verás las entregas en pendiente y, a
los 20 fallos seguidos, el endpoint deshabilitado con motivo: entregas_fallidas, como
siempre.
1.7.0 · 2026-09-20
Para quien integra, no cambia nada. Las 21 operaciones, sus respuestas y sus códigos de error son los mismos; el contrato generado solo cambia el número de versión.
Lo que cambió es cómo se prueba el servicio antes de que te llegue: un entorno de staging, junto a producción, donde se provoca a propósito lo que aquí no se puede —el proveedor externo caído, el circuito abierto, el presupuesto agotado— contra un doble del proveedor, sin gastar crédito real ni enviar un documento a nadie.
🚩 Un detalle de Watch que te beneficia sin que hagas nada. Si el cálculo de cambios del padrón fallaba por un error interno, antes se registraba como aviso y no se reintentaba: podías quedarte un día sin los webhooks de ese día. Ahora se reintenta y el fallo nos llega. Y la cadena entera —del padrón nuevo al webhook firmado— se ha ensayado de punta a punta contra un receptor que verifica la firma exactamente como describe esta documentación.
1.6.0 · 2026-09-20
Para quien integra, no cambia nada. Las 21 operaciones, sus respuestas y sus códigos de error son exactamente los mismos, y el contrato generado solo cambia el número de versión que lleva dentro. Esta entrada existe porque el changelog documenta todas las versiones que se sirven, también las que no te piden hacer nada.
Lo que cambió es el panel de operación, que es interno: una página de puesta en marcha que dice qué falta configurar y qué código de error produce cada ausencia, cuatro gráficos en el escritorio, y un repaso de todos sus textos.
🚩 Un detalle que sí puede alcanzarte, aunque no es de la API. El estado fallido de
una entrega de webhook, que la base admitía y ningún código escribía, se ha retirado. Si
alguna vez leíste ese valor en algún sitio: no existía. Una entrega fallida con reintento
pendiente es pendiente; una sin reintentos, descartado.
1.5.0 · 2026-09-20
GET /watch/webhooksdice por qué un endpoint está deshabilitado, en unmotivonuevo junto aactivo,fallos_seguidosydeshabilitado_en. §12.4 promete avisar al tenant cuando eso ocurre, y el canal para hacerlo no existe —lo que se ha roto es justo el canal que teníamos contigo—: así que se dice aquí, donde puedes consultarlo cuando quieras y sin depender de nosotros.
Es un campo nuevo en una respuesta, así que es aditivo: si tu integración ignora lo que no conoce, no tienes que hacer nada.
Lo demás de esta versión es interno y no cambia la API: Watch en el panel, el expediente de los ejercicios ARCO, la factura final de una suscripción cancelada y el detector de disco.
1.4.0 · 2026-09-20
- El contrato dice qué devuelve cada operación. Las 21 operaciones declaran
responses, los POST y DELETE de Watch declaranrequestBody, y los parámetros de query obligatorios —qen/ruc/buscar,desdeyhastaen/tipo-cambio/rango— aparecen por fin en el documento. Con esto se puede generar un cliente tipado:openapi-typescriptlo hace ytsc --strictlo compila sin un error. - Guías de inicio por lenguaje en
/docs/guias, con curl, PHP, JavaScript/TypeScript y Python. - Catálogo de eventos de webhook en
/docs/eventos, con el payload de ejemplo, el backoff y cómo verificar la firma. 🚩 Dos de los siete eventos se aceptan y no se disparan nunca: SUNAT dejó de publicar la fuente que los alimentaba. - Página de estado en
/estado: si el servicio resuelve y cómo de fresco es el dato. - El playground de
/docsresuelve también las rutas con query.
Ningún cambio es incompatible: lo que se servía antes se sigue sirviendo igual.
1.3.0 · 2026-09-19
- Los cinco indicadores sin fuente de la ficha de RUC —
es_agente_retencion,es_buen_contribuyente,es_agente_percepcion,obligado_pleyafiliado_see— pasan defalseanull. SUNAT dejó de publicar los padrones de donde salían, yfalseafirmaba lo que nadie sabe. 🚩 No los leas comofalse: en PHP y en JavaScriptnulltambién es falso, así que unif (flag)no cambia de comportamiento, pero un=== falsesí.
1.2.0 · 2026-09-19
- El presupuesto de consultas a fuentes externas tiene ahora un techo de plataforma.
Al alcanzarse, las consultas que necesitarían salir fuera responden 404 degradado
—con
meta.degradado: true— y nunca 429: no es tu presupuesto el que se agotó.
1.1.2 · 2026-09-19
- Un rechazo del proveedor externo —401, 402, 403 o 429— ya no se sirve como «no existe». Antes devolvía un 404 limpio; ahora devuelve 404 degradado, que es lo que de verdad ocurrió: no se pudo preguntar.
La versión que estás leyendo la sirve este mismo despliegue: aparece en el pie, en
/id/v1/health y dentro del contrato.