Guía de la API v1.1.0

API REST y FHIR R4 para integrar sistemas externos con los flujos clínicos de Abigail. Todo lo que ve aquí se genera desde el código, por lo que siempre coincide con el comportamiento real.

Pregunte al asistente

Responde sobre esta API usando solo la documentación. No escriba datos de pacientes, contraseñas ni llaves reales: se descartan automáticamente.

Se retiraron de su pregunta datos que parecían sensibles.

Fuentes:

Inicio rápido (5 minutos)

  1. Pida a su administrador una llave en Super Admin → API Management. Use una llave abi_test_… para pruebas y abi_live_… para producción.
  2. Compruebe la conexión (no requiere credenciales):
curl https://abigail.nfinnovations.com/api/v1/ping
  1. Consulte pacientes con su llave:
curl https://abigail.nfinnovations.com/api/v1/patients?per_page=5 \
  -H "X-API-Key: abi_test_SU_LLAVE" \
  -H "Accept: application/json"

¿Prefiere un cliente gráfico? Descargue la colección Postman o explore la referencia interactiva.

Autenticación

Hay dos formas, según quién llama:

MétodoCabeceraÚselo para
Llave de APIX-API-Key: abi_live_…Integraciones entre sistemas (servidor a servidor). Queda fija a una clínica.
Token personalAuthorization: Bearer …Apps de personal clínico. Se obtiene con usuario y contraseña.
curl -X POST https://abigail.nfinnovations.com/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"email":"medico@clinica.com","password":"••••••••••••","device_name":"mi-app","abilities":["patients:read"]}'

Seguridad: tras 5 intentos fallidos la cuenta queda bloqueada 15 minutos (desde esa IP). Los tokens caducan; nunca se emiten con permisos totales (*) y no pueden superar los de su rol. Guarde las llaves en un gestor de secretos, nunca en el código ni en el repositorio.

Permisos (abilities) por rol

El token recibe los permisos que solicite, siempre que su rol los tenga. Sin abilities recibe todos los de su rol.

PermisoQué permitesuper_admin_systemadmin_clinicadoctorenfermerosecretarialaboratoriobodega_farmaciapacientedeveloper
catalogs:readConsultar catálogos clínicos✓✓✓✓✓✓✓——
patients:readConsultar pacientes✓✓✓✓✓————
interoperability:readConsultar FHIR/HL7✓✓✓——————
interoperability:writeEnviar/ingerir FHIR/HL7✓✓———————
medical-records:readLeer el expediente: consultas, diagnósticos y tratamientos✓✓✓✓—————
prescriptions:readLeer prescripciones médicas✓✓✓✓—————
recipes:readLeer recetas emitidas✓✓✓✓——✓——
recipes:writeEmitir la receta de una consulta (médico tratante)✓—✓——————
recipes:dispenseRegistrar la dispensación de una receta✓—————✓——
practitioners:readConsultar profesionales de la clínica✓✓✓✓✓————
patients:writeRegistrar pacientes✓✓——✓————
consents:writeRegistrar o retirar el consentimiento del paciente (solo personal de la clínica)✓✓✓—✓————
encounters:writeRegistrar consultas con diagnóstico y prescripción (requiere profesional responsable)✓—✓——————
appointments:readConsultar la agenda y la disponibilidad✓✓✓✓✓————
appointments:writeAgendar turnos y cambiar su estado✓✓——✓————

Alcance por clínica

Cada petición opera sobre una sola clínica; nunca se mezclan datos de varias. Una llave de API queda fija a la clínica con la que se emitió (si no tiene clínica asignada, no devuelve datos). Un token de usuario con varias clínicas indica cuál usar con X-Clinic-ID: 12. Pedir un recurso de otra clínica responde 404, igual que si no existiera.

Formato de respuestas

// Éxito
{ "success": true, "message": "OK", "data": { ... } }

// Error
{ "success": false, "message": "Datos inválidos.", "errors": { "email": ["El campo email es obligatorio."] }, "request_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301" }

Fechas en ISO-8601. Los textos de mensaje están en español. Excepción: los endpoints FHIR devuelven recursos y OperationOutcome estándar (application/fhir+json).

Paginación

Los listados aceptan ?page=1&per_page=25 (máximo 100) y devuelven meta.page, meta.per_page y meta.total. Itere hasta que page × per_page ≥ total.

Errores

CódigoCausa habitualQué hacer
401Llave o token ausente, inválido, expirado o revocadoVerifique la cabecera; renueve el token o pida una llave nueva.
403Falta un permiso (abilities), rol insuficiente o política de acceso a datos clínicosEl mensaje indica el permiso. Pida al administrador que lo habilite.
404El recurso no existe o pertenece a otra clínicaRevise el identificador y la clínica (X-Clinic-ID).
422Datos inválidosLea errors: indica cada campo y la razón.
429Límite de peticiones o bloqueo por intentos fallidosEspere lo indicado en Retry-After y reintente con espera creciente.
5xxError del servidorReintente; si persiste, contacte soporte con el X-Request-Id.

Reintentos seguros (idempotencia)

Si una escritura (POST, PUT, PATCH, DELETE) se corta por red o tiempo de espera, reintentarla podría duplicar la consulta, receta o reclamo. Envíe una clave única por operación y el reintento devolverá la respuesta original:

curl -X POST https://abigail.nfinnovations.com/api/v1/emergency/form-008 \
  -H "X-API-Key: abi_test_SU_LLAVE" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -H "Content-Type: application/json" -d '{ ... }'
  • Mismo Idempotency-Key y mismo cuerpo → misma respuesta, con la cabecera Idempotent-Replayed: true.
  • Misma clave con otro cuerpo → 422. Aún en proceso → 409 con Retry-After.
  • Solo se conservan respuestas exitosas (2xx), durante 24 horas. Un error libera la clave para reintentar.
  • Es opcional: sin la cabecera todo funciona como antes. Use un UUID por operación.

Límites de uso

Cada llave tiene un límite de peticiones por minuto y una cuota mensual según su plan. Al superarlo recibe 429 con las cabeceras Retry-After, X-RateLimit-Limit y X-RateLimit-Remaining. Consulte su plan y consumo en API Management.

Datos clínicos y auditoría

Los datos de pacientes son información de salud protegida. Cada acceso exitoso queda registrado (quién, desde dónde, qué ruta, qué clínica). Los endpoints que exponen historia clínica están sujetos a la política de acceso de la clínica (consentimiento, justificación o 2FA según su configuración). No almacene ni registre en logs datos clínicos que no necesite, y use siempre HTTPS.

FHIR R4 e interoperabilidad

  • Capacidades del servidor: /api/v1/fhir/metadata
  • Descubrimiento SMART on FHIR: /api/v1/.well-known/smart-configuration
  • Resumen internacional del paciente (IPS): GET /api/v1/ips/patient/{id}
  • HL7 v2 (MLLP): puerto 2575, para equipos de laboratorio. Aún no tiene guía pública; solicítela a soporte si su integración lo necesita.

Versiones y cambios

La versión mayor va en la URL (/api/v1). Dentro de una versión solo se añaden campos y endpoints (compatibles). Un cambio incompatible se publica como /v2, y la versión anterior se mantiene al menos 6 meses con aviso previo. Un endpoint en retirada responde con las cabeceras Deprecation: true y Sunset: <fecha> (más un enlace rel="deprecation") y aparece como deprecated en el contrato OpenAPI: monitoree esas cabeceras en su cliente.

v1.1.0 · 2026-10-04 · feature
  • Nueva cabecera opcional Idempotency-Key en las escrituras: un reintento con la misma clave no duplica la operación.
  • Los endpoints en retirada se anuncian con las cabeceras Deprecation y Sunset y se marcan deprecated en el contrato.
v1.0.0 · 2026-10-04 · security
  • Los tokens ya no admiten el permiso *: cada token recibe un subconjunto de los permisos de su rol.
  • Las llaves de API quedan acotadas a una clínica (api_clients.clinic_id); sin clínica asignada no devuelven datos.
  • Todas las respuestas incluyen X-Request-Id; los errores incluyen request_id.
  • El contrato OpenAPI se genera desde el código y se publica una colección Postman.

Descargas

  • Contrato OpenAPI 3 (JSON) — impórtelo en su generador de clientes (openapi-generator, NSwag, etc.).
  • Colección Postman
  • Cliente TypeScript (Node 18+ y navegadores, sin dependencias) y cliente PHP (cURL, sin dependencias). Se generan del contrato vigente: incluyen autenticación, X-Clinic-ID, Idempotency-Key, reintentos con Retry-After y un error con el X-Request-Id.

Soporte

Escriba a soporte@abigailsoft.com e incluya el valor de X-Request-Id de la petición con problemas: con él localizamos el caso exacto sin pedirle datos del paciente.