Catálogo de errores
Ramifica por el status HTTP, nunca por el cuerpo
La API emite tres formas de error distintas, según qué capa responda:
| Forma | Quién la emite | Ejemplo |
|---|---|---|
{ "message": "…" } | El manejador global de errores | {"message":"No pudimos encontrar lo que buscas"} |
{ "error": "…" } | Los middlewares de RENAP y RTU | {"error":"Rate limit exceeded."} |
{ "error": true, "message": "…" } | Validadores antiguos, en superficies que este portal no documenta | {"error":true,"message":"…"} |
:::danger El campo error no es fiable
Tiene tres comportamientos: ausente (manejador global), cadena de texto con el mensaje
(RENAP y RTU) y booleano true en otras superficies. Un cliente que haga
if (response.error) acertará unas veces y fallará otras, y uno que lea response.error como
texto se romperá donde sea booleano.
El discriminante es el status HTTP. Trata message y error como texto para personas.
:::
Además, una ruta que no existe devuelve texto plano, no JSON:
404: Not Found
Si tu cliente hace JSON.parse sin comprobar el Content-Type, un typo en la URL se te
presentará como un error de parseo en vez de como un 404.
Mensajes por defecto de la API
Estos son los textos exactos que produce el backend cuando la operación no aporta uno propio:
| Status | Mensaje por defecto | Significado |
|---|---|---|
400 | La información enviada no es correcta | La petición no pasó la validación |
401 | Ingresa tus credenciales | No hay identidad válida |
402 | No tienes método de pago válido | El contribuyente no tiene medio de pago |
403 | No tienes permiso para realizar esta acción | Identidad válida, permiso insuficiente |
404 | No pudimos encontrar lo que buscas | El recurso no existe, o no es del contribuyente |
409 | Ya existe algo más con esos datos | Colisión con un registro existente |
500 | Algo salió mal | Fallo no controlado |
La mayoría de las operaciones envían un mensaje más específico en lugar de estos. El status es el mismo.
Errores de autenticación de integrador
| Status | Mensaje | Causa | Qué hacer |
|---|---|---|---|
401 | Integración no encontrada con estas credenciales. | x-integracion-login o x-integracion-token incorrectos, o solo uno de los dos | Revisa las credenciales del entorno al que pegas: las de dev no valen en producción |
401 | Error de autenticación. Por favor vuelva a iniciar sesión. (con resetLogin: true) | Un token Bearer inválido o vencido. Un integrador no envía Authorization, así que algo por el camino la está añadiendo | Revisa tu proxy y tu cliente HTTP |
Errores de RENAP y RTU
Estas dos rutas responden con la clave error y valor de texto:
| Status | Cuerpo | Causa |
|---|---|---|
400 | {"error":"CUI is required"} | Falta el CUI |
400 | {"error":"Array of NITs is required"} | nits ausente, vacío o no es array |
403 | {"error":"Integration authentication required."} | Sin credenciales de integración válidas |
403 | {"error":"RENAP access not enabled."} | La integración no tiene RENAP habilitado |
403 | {"error":"RTU access not enabled."} | La integración no tiene RTU habilitado |
429 | {"error":"Rate limit exceeded."} | Límite por minuto de la integración excedido |
Ver Consultas.
Errores de los catálogos (/catalogos/cui-nit, /catalogos/rtu, /catalogos/omisos)
A diferencia de RENAP y RTU, estas tres rutas responden con la clave message, como el resto
de la API. Los mensajes van sin tildes, tal como los emite la API:
| Status | Cuerpo | Causa |
|---|---|---|
400 | {"message":"Envia un NIT o un CUI para consultar."} | Ni nit ni cui llegaron como texto no vacío |
400 | {"message":"Los datos de la consulta no son validos."} | La fuente rechazó los datos de la consulta |
401 | {"message":"Integración no encontrada con estas credenciales."} | Las credenciales de integración no corresponden a ninguna integración, o llegó solo uno de los dos headers |
401 | {"message":"No fue posible autenticar la consulta. Escribe a soporte."} | La fuente rechazó la autenticación de la consulta |
402 | {"message":"Tu integracion no tiene saldo disponible. Recarga para seguir consultando."} | El saldo prepago de tu integración se agotó; la consulta no llegó a la fuente y no se cobró |
402 | {"message":"El servicio de consultas no tiene saldo disponible. Escribe a soporte."} | El servicio de consultas no tiene saldo disponible |
403 | {"message":"Se requieren credenciales de integracion."} | Sin credenciales de integración válidas |
403 | {"message":"Esta consulta no esta habilitada para tu integracion."} | Tu integración no tiene la bandera de este catálogo activa |
403 | {"message":"Esta consulta no esta habilitada. Escribe a soporte."} | La fuente le negó el acceso a la consulta |
404 | {"message":"No encontramos informacion para los datos enviados."} | No hay registro para el NIT o CUI enviado |
429 | {"message":"Demasiadas consultas seguidas. Intenta en un minuto."} | Límite de 30/min de Tributax excedido — compartido entre los tres catálogos |
429 | {"message":"Demasiadas consultas seguidas. Intenta de nuevo en unos minutos."} | La fuente está limitando las consultas |
502 | {"message":"El servicio de consultas no esta disponible en este momento."} | La fuente no respondió |
Ver Catálogos.
429 — hay varios límites
| Capa | Límite | Cuerpo |
|---|---|---|
| Global, por IP | 100 / 15 min | Cuerpo por defecto de express-rate-limit |
| RENAP, por integración | 30 / min | {"error":"Rate limit exceeded."} |
RTU (/rtu/nits), por integración | 50 / min | {"error":"Rate limit exceeded."} |
Catálogos (/catalogos/*), por integración, compartido entre los tres | 30 / min | {"message":"Demasiadas consultas seguidas. Intenta en un minuto."} |
Ninguno devuelve Retry-After. Ver Entornos y límites.
📄 Estado de verificación: los mensajes por defecto se transcribieron literalmente de
server/src/utilities/error.ts y una prueba automatizada comprueba que siguen coincidiendo. Las
respuestas no se han ejercido contra el entorno desplegado en esta entrega.