Guías
Errores
El formato de los errores (RFC 9457), qué significa cada código HTTP y la lista de tipos de error de la API con su causa y su solución.
Última revisión: 1 de octubre de 2026
Formato
Todos los errores siguen el estándar Problem Details (RFC 9457), con Content-Type: application/problem+json:
{
"type": "/errors/validation-error",
"title": "Error de validación",
"status": 400,
"detail": "estimatedMinutes must be divisible by 10",
"instance": "/api/integrations/v1/visits",
"errors": [
{ "field": "estimatedMinutes", "message": "estimatedMinutes must be divisible by 10" }
],
"timestamp": "2026-10-01T09:10:00.000Z"
}| Campo | Descripción |
|---|---|
type | Identificador estable del error. Es una ruta relativa (/errors/…). Tu código debe decidir qué hacer mirando status y type, nunca el texto. |
title | Resumen corto y legible. Puede cambiar de redacción. |
status | El mismo código HTTP de la respuesta. |
detail | Explicación concreta de este caso («El aviso AV-000123 está en estado EN_ROUTE…»). Para mostrar a tu operador o registrar. |
instance | La ruta de la petición que falló. |
errors | Solo en errores de validación: un elemento por campo, con su ruta (patient.documentNumber, address.postalCode). |
timestamp | Cuándo se produjo. |
Algunos errores llevan campos adicionales con datos del caso. Ignora los que no conozcas.
Los mensajes de errors[] en los errores de validación de formato son los del validador, en inglés (must be a UUID, should not exist): están pensados para el desarrollador, no para el usuario final. Los errores de negocio (detail) sí están redactados para poder enseñarlos.
Cuando nos escribas por un error, incluye el type, el detail, el instance, el timestamp y la cabecera X-Serad-Environment: con eso lo localizamos enseguida.
Códigos HTTP
| Código | Significado | ¿Reintentar? |
|---|---|---|
200 OK | Correcto. En un alta, también es la respuesta a una repetición con la misma Idempotency-Key. | — |
201 Created | Aviso creado. | — |
400 Bad Request | La petición no es válida: un campo mal formado, un tipo de servicio que no tienes, una regla de negocio. | No: corrígela. |
401 Unauthorized | Falta la clave, no es válida, está revocada o caducada, o es de otro entorno. | No. |
403 Forbidden | La clave es válida pero no tiene el ámbito necesario. | No. |
404 Not Found | El aviso (o el informe) no existe o no es tuyo. También las rutas de sandbox en producción. | No. |
409 Conflict | El estado actual no lo permite (cancelar un aviso en camino) o conflicto de idempotencia. | Solo idempotency-in-progress. |
429 Too Many Requests | Has superado el límite de peticiones. | Sí, tras Retry-After. |
500 Internal Server Error | Error nuestro. | Sí, con espera exponencial. |
502 / 503 / 504 | La API no está disponible momentáneamente (despliegue, mantenimiento). | Sí, con espera exponencial. |
Tipos de error
Autenticación y límites
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/provider-api/invalid-key | 401 | No hay cabecera X-Api-Key, o la clave no existe, está revocada o caducada, o tu organización está inactiva. | Revisa que envías la clave completa en X-Api-Key. Si es correcta, escríbenos con su prefijo. |
/errors/provider-api/wrong-environment | 401 | Clave de pruebas contra producción, o de producción contra pruebas. | Usa srd_test_… con https://sandbox-api.saludenruta.es/api/integrations/v1 y srd_live_… con https://api.saludenruta.es/api/integrations/v1. Ver entornos. |
/errors/provider-api/scope-missing | 403 | La clave no tiene el ámbito que pide el endpoint (detail dice cuál). | Pide una clave con ese ámbito. Ver ámbitos. |
/errors/provider-api/rate-limited | 429 | Has superado las peticiones por minuto de la clave. | Espera Retry-After segundos. Usa webhooks en lugar de consultas en bucle. |
Idempotencia
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/provider-api/idempotency-key-invalid | 400 | La Idempotency-Key tiene más de 200 caracteres. | Usa una clave más corta. |
/errors/provider-api/idempotency-key-reused | 409 | Has usado la misma Idempotency-Key con un cuerpo distinto en las últimas 24 h. | Genera una clave por alta; si es un reintento, envía exactamente el mismo cuerpo. |
/errors/provider-api/idempotency-in-progress | 409 | La primera petición con esa clave aún se está procesando. | Espera unos segundos y reintenta con la misma clave. |
Alta de avisos
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/validation-error | 400 | Uno o varios campos no cumplen el formato (obligatorio que falta, longitud, enumerado…) o hay campos que la API no conoce (property … should not exist). errors[] dice cuáles. | Corrige los campos indicados. Ver campos del alta. |
/errors/provider-api/service-type-required | 400 | No has enviado ni serviceTypeCode ni serviceTypeId. | Envía serviceTypeCode (recomendado). |
/errors/provider/service-type-not-allowed | 400 | Ese tipo de servicio no está en tu catálogo (no tiene precio en tu tarifa vigente) o el código no existe. | Lee tu catálogo y usa uno de sus code. |
/errors/provider/insurer-not-managed | 400 | El insurerId no es una de tus aseguradoras, o no eres intermediario. | Usa un id de catalog.insurers del mismo entorno, o no envíes insurerId. |
/errors/visits/external-ref-required | 400 | Tu contrato exige nº de expediente y no lo has enviado. | Envía externalRef. |
/errors/visits/invalid-schedule | 400 | La franja de la cita no es coherente (fin sin inicio, o fin antes que inicio). | Envía scheduledFrom y estimatedMinutes, sin scheduledTo. |
/errors/visits/schedule-in-past | 400 | La cita empieza más de 15 minutos en el pasado. | Revisa la fecha y la zona horaria de scheduledFrom. |
/errors/visits/schedule-beyond-horizon | 400 | La cita está a más de 90 días vista. | Prográmala más cerca, o envíala más adelante. |
/errors/visits/provider-inactive | 400 | Tu organización está inactiva y no admite avisos nuevos. | Contacta con nosotros. |
/errors/patients/document-number-required | 400 | Has indicado documentType (DNI, NIE o pasaporte) sin documentNumber. | Envía el número, o documentType: "NONE". |
/errors/patients/document-not-allowed | 400 | Has enviado documentNumber con documentType: "NONE". | Indica el tipo de documento correcto. |
/errors/patients/document-invalid | 400 | El DNI o NIE no tiene un formato válido o la letra de control no cuadra. | Revisa el documento con el paciente. |
/errors/patients/not-found | 404 | El patientId no existe o no es de un aviso tuyo. | Envía los datos del paciente en patient. |
/errors/dates/in-future | 400 | Una fecha que no puede ser futura lo es (p. ej. birthDate, o dateFrom en el listado). | Corrige la fecha. |
/errors/dates/range-invalid | 400 | En el listado, dateTo es anterior a dateFrom. | Corrige el rango. |
Consulta, cancelación e informe
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/visits/not-found | 404 | El aviso no existe, es de otro proveedor o es de otro entorno. | Comprueba el id y el entorno. Puedes buscarlo por externalRef. |
/errors/validation-error | 400 | El id de la ruta no es un UUID. | Usa el id del aviso, no su code. |
/errors/provider/visit-not-cancellable | 409 | El aviso ya no está PENDING ni ASSIGNED (la unidad va de camino, está en el domicilio, o ya terminó o se canceló). | Llama a la centralita (+34 611 673 280). Ver cancelar. |
/errors/provider/report-not-available | 404 | No hay informe firmado y compartido, o el paciente no ha consentido. | Espera al webhook report.shared. Sin consentimiento no habrá informe. |
Sandbox
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/sandbox/only-in-sandbox | 404 | Has llamado a /sandbox/… en producción. | Esas rutas solo existen en https://sandbox-api.saludenruta.es/api/integrations/v1. |
/errors/sandbox/visit-not-advanceable | 400 | Has pedido mover un aviso a un estado anterior o no permitido (p. ej. de EN_ROUTE a ASSIGNED). | Ver simulación manual. |
Del servidor
type | Estado | Causa | Solución |
|---|---|---|---|
/errors/internal-error | 500 | Error inesperado de nuestro lado. | Reintenta con espera exponencial. Si persiste, escríbenos con el timestamp y el instance. |
/errors/rate-limited | 429 | Límite general de la plataforma (distinto del de tu clave). | Igual que provider-api/rate-limited: espera Retry-After. |
¿Falta algo o algo no cuadra con lo que ves? Escribe al equipo técnico: info@saludenruta.es.
