Guías
Sandbox y simulador
Cómo funciona el entorno de pruebas, el simulador que hace avanzar los avisos, el modo manual con X-Sandbox-Simulation, los endpoints /sandbox/visits/{id}/advance y /sandbox/reset, y los escenarios de prueba recomendados.
Última revisión: 1 de octubre de 2026
Qué es
El sandbox es un entorno de pruebas aislado para desarrollar y validar tu integración sin tocar nada real: otro despliegue de la misma API, con su propia base de datos, en https://sandbox-api.saludenruta.es/api/integrations/v1. Allí:
- Las rutas, los campos, los errores, las firmas y los reintentos de los webhooks son los mismos que en producción.
- Tu proveedor está configurado como en producción: mismo tipo, mismo catálogo de servicios (con otros
id; usa los códigos, ver entornos), mismas aseguradoras finales y la misma exigencia de nº de expediente. - No hay centralita ni unidades reales: los avisos los mueve un simulador.
- No sale ningún correo, notificación, receta ni aviso al personal, y no se factura nada.
- Las claves son
srd_test_…. Una clave de producción aquí, o una de pruebas en producción, recibe401/errors/provider-api/wrong-environment. - Todas las respuestas llevan
X-Serad-Environment: sandbox.
El simulador
Cuando creas un aviso en el sandbox, el simulador lo hace avanzar solo, un paso cada 20 segundos:
PENDING ──20 s──▶ ASSIGNED ──20 s──▶ EN_ROUTE ──20 s──▶ ON_SITE ──20 s──▶ FINISHED (outcome: ATTENDED)- En cada paso se envían los mismos webhooks que en producción (
visit.assigned,visit.en_route…), con la misma forma, firma y reintentos. - Al asignar, el simulador pone una unidad ficticia del día, médica o de enfermería según el tipo de servicio, así que
unitTypeyunitsalen como en producción. - Con el aviso en camino,
GET /visits/{id}/etadevuelve una hora estimada simulada (la llegada es el siguiente paso). - El resultado final es siempre
ATTENDED(atendido). Para otros finales, o para cancelar, usa la simulación manual. - Los avisos acaban en
FINISHED: en el sandbox no hay validación ni facturación, así que nunca llegan aINVOICEDni se envíavisit.invoiced.
Simulación manual
Para probar un escenario concreto (cancelar con la unidad asignada, un aviso que se queda en camino un buen rato), crea el aviso con la cabecera X-Sandbox-Simulation: manual. Ese aviso no avanza solo: lo mueves tú.
curl -X POST "$SERAD_API_URL/visits" \
-H "X-Api-Key: $SERAD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: prueba-manual-0001" \
-H "X-Sandbox-Simulation: manual" \
-d @aviso.jsonAvanzar un aviso
POST /sandbox/visits/{id}/advance (ámbito visits:write) lo lleva al siguiente estado, o al que indiques en to:
# Al siguiente estado (PENDING → ASSIGNED)
curl -X POST "$SERAD_API_URL/sandbox/visits/c6a3c348-40b6-4158-a44a-7d85f01a0201/advance" \
-H "X-Api-Key: $SERAD_API_KEY"
# Directamente a en el domicilio (pasa por los intermedios)
curl -X POST "$SERAD_API_URL/sandbox/visits/c6a3c348-40b6-4158-a44a-7d85f01a0201/advance" \
-H "X-Api-Key: $SERAD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "ON_SITE" }'to | Efecto |
|---|---|
| (sin cuerpo) | Al siguiente estado del flujo. |
ASSIGNED | Asigna una unidad ficticia. |
EN_ROUTE | La unidad sale. |
ON_SITE | La unidad llega. |
FINISHED | Termina la atención con outcome: ATTENDED. |
CANCELLED | Cancela el aviso (desde PENDING, ASSIGNED o EN_ROUTE), como si lo hiciera la centralita, sin cargo. |
- Si saltas estados (de
PENDINGaON_SITE), el aviso pasa por los intermedios y recibes el webhook de cada uno, en orden. - La respuesta es el aviso con su línea de tiempo, como
GET /visits/{id}. - Pedir un estado anterior o no permitido (de
EN_ROUTEaASSIGNED, o mover un aviso ya finalizado) responde400/errors/sandbox/visit-not-advanceable, con un mensaje como «El aviso AV-000004 está en camino y no puede pasar a «asignado».». - También puedes usar
advancecon avisos automáticos para no esperar los 20 segundos.
Limpiar el entorno
POST /sandbox/reset (ámbito visits:write) borra todos tus avisos de prueba y los pacientes que solo aparecían en ellos, para empezar una batería de pruebas desde cero:
curl -X POST "$SERAD_API_URL/sandbox/reset" \
-H "X-Api-Key: $SERAD_API_KEY"{ "status": 200, "data": { "deletedVisits": 12 }, "message": "Operación realizada correctamente" }Solo afecta a tu organización y solo al sandbox. Tu catálogo, tus claves y tus webhooks no se tocan.
Escenarios de prueba recomendados
Antes de pedir la clave de producción, recorre estos escenarios en el sandbox. Son los que repasaremos contigo en la validación (ver la lista de comprobación).
| # | Escenario | Cómo | Qué comprobar |
|---|---|---|---|
| 1 | Aviso urgente completo | Alta con priority: "URGENT", modo automático. | Recibes, en este orden lógico, visit.created, visit.assigned, visit.en_route, visit.on_site y visit.finished, todos con firma válida; tu sistema refleja cada estado y el outcome. |
| 2 | Cita programada | Alta con priority: "SCHEDULED", scheduledFrom mañana a las 9:00 (+02:00/+01:00) y estimatedMinutes: 40. | La respuesta trae scheduledFrom y scheduledTo (= inicio + 40 min). Prueba también una cita en el pasado y a más de 90 días: 400. |
| 3 | Cancelación permitida | Alta en modo manual, advance a ASSIGNED, y POST /visits/{id}/cancel. | 200, status: "CANCELLED", cancelledWithCharge: false y webhook visit.cancelled. |
| 4 | Cancelación no permitida | Alta en modo manual, advance a EN_ROUTE, y cancelar. | 409 /errors/provider/visit-not-cancellable, y tu sistema le dice al operador que llame a la centralita. |
| 5 | Paciente repetido | Dos avisos con el mismo documento y fecha de nacimiento. | Los dos se crean sin error. patientName es, en cada uno, el nombre que enviaste en ese aviso. |
| 6 | Idempotencia | Repite la misma alta con la misma Idempotency-Key; después, con la misma clave y otro motivo. | Primero 201; la repetición, 200 con el mismo id y Idempotent-Replayed: true; con otro cuerpo, 409 idempotency-key-reused. Ningún aviso duplicado. |
| 7 | Webhook caído y reintentos | Haz que tu receptor responda 500 (o apágalo), crea un aviso y, al minuto, vuelve a encenderlo. | Recibes los reintentos con el mismo X-Serad-Delivery y firmas nuevas; tu sistema procesa cada evento una sola vez. |
| 8 | Firma incorrecta | Envía a tu receptor una petición con el cuerpo modificado o un timestamp de hace 10 minutos. | Tu receptor responde 401 y no procesa nada. |
| 9 | Errores de validación | Alta sin reason, con un DNI con la letra mal, con estimatedMinutes: 45 y con un campo inventado. | 400 con errors[] señalando el campo; tu sistema muestra el problema sin reintentar. |
| 10 | Límite de peticiones | Lanza más peticiones por minuto que tu X-RateLimit-Limit. | 429 con Retry-After; tu cliente espera y reintenta. |
| 11 | Clave de otro entorno | Llama al sandbox con una clave srd_live_… (o al revés). | 401 wrong-environment; tu configuración no lo permite por error. |
Para cada escenario, empieza con POST /sandbox/reset si quieres un entorno limpio.
Datos de prueba
Usa datos inventados pero con formato válido, porque se validan igual que en producción:
| Dato | Valor de ejemplo |
|---|---|
| DNI válido | 12345678Z, 00000000T, 99999999R |
| NIE válido | X1234567L, Y0000000Z |
| DNI no válido (letra incorrecta) | 12345678A |
| Teléfono | +34600000001 … +34600000099 |
| Dirección | Cualquier calle real de Madrid, por ejemplo Calle de Alcalá 120, 28009, Madrid. |
| Fecha de nacimiento | 1948-05-17, 2019-03-02 (pediatría, con documentType: "NONE") |
| Nº de expediente | TEST-0001, TEST-0002… |
¿Falta algo o algo no cuadra con lo que ves? Escribe al equipo técnico: info@saludenruta.es.
