Download OpenAPI specification:
Contrato de la API de la red: recetas y dispensación, ingesta por correo, adaptadores, identidad y verificación de asegurados, claims y liquidación, financiamiento, órdenes de estudios con visación, webhooks y consumo.
API para emitir recetas médicas desde cualquier sistema clínico y rutearlas a la red de farmacias conectadas, con dispensación granular por línea de medicamento (parcial, en varias farmacias/sucursales, con trazabilidad de lote y caducidad).
POST /prescriptions), consultan
las suyas y las anulan. Reciben webhooks de dispensación.POST /prescriptions/{id}/dispensations).Hay tres puertas de entrada, de menor a mayor esfuerzo de integración:
POST /intake): el médico manda su PDF de
siempre. Cero cambios en el sistema del hospital.POST /adapters/{adapterId}/prescriptions): el hospital emite en
su propio formato (FHIR R4, el suyo) y la plataforma lo traduce.POST /prescriptions): el modelo canónico directo.Las tres desembocan en el mismo schema canónico y producen la misma receta.
MedicationRequest,
MedicationDispense) sin exigir cumplimiento FHIR completo: nombres y estructura
alineados para que una integración estándar futura no requiera rediseño.signature.type): certificado digital, para quienes lo poseen, o
imagen de firma escaneada. Qué modalidad es exigible depende de la normativa de
cada país.GET /prescriptions/{id}/document. Los campos estructurados son una extracción
derivada — sirven para cargar el sistema de la farmacia sin tipeo, pero ante
discrepancia el farmacéutico dispensa mirando el documento.GET /usage.X-API-Key (permisos equivalentes a scopes, allowlist de IPs,
rate limiting y expiración configurables por llave).{ "error": { "code", "message", "details" } }.Idempotency-Key para reintentos seguros.X-RateLimit-Limit, X-RateLimit-Remaining.Crea una receta en la plataforma y la hace disponible para la red de farmacias. Pensado para clínicas y sistemas emisores (también lo usa internamente la ingesta por email una vez validada por un humano).
Requiere scope prescriptions:write.
| Idempotency-Key | string <= 128 characters Clave única elegida por el cliente (UUID recomendado). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta original sin duplicar la operación. |
| externalId | string ID de la receta en el sistema emisor (único por organización). |
required | object (Patient) Datos mínimos del paciente (forma FHIR |
required | object (Practitioner) Profesional prescriptor (forma FHIR |
Array of objects (Diagnosis) Diagnósticos CIE-11. Permanecen en la plataforma y la clínica emisora; nunca se exponen a farmacias. | |
required | Array of objects (MedicationLineCreate) non-empty |
object (Signature) Firma del médico sobre la receta. Dos modalidades:
| |
| notes | string Notas para la farmacia (no clínicas). |
| usesAllowed | integer [ 1 .. 24 ] Default: 1 Utilizaciones autorizadas por el médico. Default 1: un solo uso —
agotadas las cantidades, la receta no puede volver a dispensarse.
Un valor mayor la hace recurrente (p. ej. 3 retiros mensuales para
un tratamiento crónico): cada utilización habilita de nuevo
|
| expiresAt | string <date-time> Vencimiento de la receta. Si se omite, aplica el default de la plataforma (30 días, a validar con partners). |
{- "externalId": "REC-0142-2026",
- "patient": {
- "identityType": "cedula",
- "identityNumber": "4567890",
- "firstName": "María",
- "lastName": "González",
- "birthDate": "1988-04-12",
- "gender": "female",
- "phone": "0981 123 456"
}, - "practitioner": {
- "name": "Dr. Juan Pérez",
- "licenseNumber": "12345",
- "specialty": "Medicina interna"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 21,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "cada 8 horas",
- "duration": "7 días"
}, - "substitutionAllowed": true
}, - {
- "name": "Paracetamol 500 mg comprimidos",
- "atcCode": "N02BE01",
- "quantityPrescribed": 10,
- "unit": "comprimido",
- "dosageInstruction": {
- "text": "1 comprimido cada 8 horas si hay fiebre"
}
}
], - "signature": {
- "type": "scanned_image",
- "value": "iVBORw0KGgoAAAANSUhEUgAA..."
}, - "expiresAt": "2026-09-25T00:00:00Z"
}{- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z"
}prescriptions:read): requiere patientIdentityNumber (el
paciente presenta su documento en mostrador). Devuelve solo recetas
dispensables (active o partially_dispensed) salvo que se filtre por estado.prescriptions:write): lista las recetas emitidas por la propia
organización; patientIdentityNumber es opcional.| patientIdentityNumber | string Documento de identidad del paciente. Obligatorio para farmacias. |
| status | string (PrescriptionStatus) Enum: "active" "partially_dispensed" "dispensed" "cancelled" "expired" Estado de la receta (mapeo FHIR
Regla de utilizaciones: la receta es de un solo uso por defecto
( |
| externalId | string ID de la receta en el sistema emisor (solo visible para la clínica emisora). |
| createdFrom | string <date-time> |
| createdTo | string <date-time> |
| limit | integer [ 1 .. 100 ] Default: 50 |
| offset | integer >= 0 Default: 0 |
{- "data": [
- {
- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0,
- "hasMore": true
}
}Incluye el estado de dispensación por línea (cantidades dispensadas/restantes y
en qué farmacia/sucursal). Requiere prescriptions:read, o prescriptions:write
si la consulta la clínica emisora.
| prescriptionId required | string ID de la receta en la plataforma ( |
{- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z"
}Solo la clínica emisora (prescriptions:write). No se puede anular una receta
con dispensaciones registradas (PRESCRIPTION_HAS_DISPENSATIONS); las líneas aún
no dispensadas quedan bloqueadas al anular.
| prescriptionId required | string ID de la receta en la plataforma ( |
| reason | string Motivo de la anulación (queda en auditoría). |
{- "reason": "string"
}{- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z"
}Devuelve el documento original tal como lo emitió el médico (PDF o imagen), cuando la receta entró por ingesta. Es el documento autoritativo: el farmacéutico dispensa mirándolo. Los datos estructurados de la receta son una extracción derivada, útil para cargar el sistema de la farmacia sin tipeo, pero no reemplazan al documento — ante discrepancia, manda el documento.
Acceso:
active o
partially_dispensed), o siempre que esa misma farmacia haya registrado una
dispensación sobre ella (para su respaldo posterior).Devuelve 404 si la receta se emitió por API nativa o por adaptador, porque en
ese caso no existe documento original: la receta es el dato estructurado.
| prescriptionId required | string ID de la receta en la plataforma ( |
{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}Registra la entrega de una o más líneas de la receta por una farmacia.
Soporta dispensación parcial: por línea se indica la cantidad entregada, que
no puede exceder la restante (QUANTITY_EXCEEDS_REMAINING). Distintas líneas (o
el resto de una línea) pueden dispensarse después en otra farmacia o sucursal.
Requiere scope dispensations:write. La operación es atómica: si alguna línea
falla la validación, no se registra nada.
| prescriptionId required | string ID de la receta en la plataforma ( |
| Idempotency-Key | string <= 128 characters Clave única elegida por el cliente (UUID recomendado). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta original sin duplicar la operación. |
| branchCode | string Código de la sucursal de la farmacia (registrada en la plataforma). |
| dispensedBy required | string Identificación del profesional que dispensa. |
required | Array of objects (DispensationItemCreate) non-empty |
| paymentMethod | string Enum: "cash" "card" "insurance" "other" |
| receiptNumber | string |
| notes | string |
{- "branchCode": "SUC-CENTRO",
- "dispensedBy": "Q. F. Laura Ríos",
- "items": [
- {
- "lineId": "line_01J8ZC5R7T",
- "quantity": 10,
- "unitPrice": 1.25,
- "batchNumber": "L2406-118",
- "expiryDate": "2027-03-31"
}
], - "paymentMethod": "cash",
- "receiptNumber": "F-000123"
}{- "id": "disp_01J8ZD8N3V",
- "prescriptionId": "string",
- "pharmacy": {
- "id": "string",
- "name": "string",
- "branchCode": "string",
- "branchName": "string"
}, - "dispensedBy": "string",
- "items": [
- {
- "lineId": "string",
- "quantity": 1,
- "substitutedBy": "string",
- "unitPrice": 0,
- "batchNumber": "string",
- "expiryDate": "2019-08-24",
- "notes": "string",
- "medicationName": "string",
- "totalPrice": 0
}
], - "totalAmount": 0,
- "paymentMethod": "string",
- "receiptNumber": "string",
- "notes": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "prescriptionStatus": "active"
}| prescriptionId required | string ID de la receta en la plataforma ( |
{- "data": [
- {
- "id": "disp_01J8ZD8N3V",
- "prescriptionId": "string",
- "pharmacy": {
- "id": "string",
- "name": "string",
- "branchCode": "string",
- "branchName": "string"
}, - "dispensedBy": "string",
- "items": [
- {
- "lineId": "string",
- "quantity": 1,
- "substitutedBy": "string",
- "unitPrice": 0,
- "batchNumber": "string",
- "expiryDate": "2019-08-24",
- "notes": "string",
- "medicationName": "string",
- "totalPrice": 0
}
], - "totalAmount": 0,
- "paymentMethod": "string",
- "receiptNumber": "string",
- "notes": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "prescriptionStatus": "active"
}
]
}Se envía a farmacias suscritas cuando una receta entra en estado active.
Todas las entregas de webhooks incluyen los headers:
X-Emedic-Event: tipo de evento.X-Emedic-Delivery: ID único de la entrega (para deduplicar reintentos).X-Emedic-Timestamp: epoch en segundos.X-Emedic-Signature: v1= + HMAC-SHA256 hex de "{timestamp}.{cuerpo}" con el
secret del endpoint. Rechazar si la firma no coincide o el timestamp tiene
más de 5 minutos.Entregas con reintento y backoff exponencial durante 24 h ante respuestas no 2xx.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Se envía a la clínica emisora cada vez que una farmacia registra una dispensación.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Evento DIRIGIDO a cada clínica que ya le emitió una receta a ese paciente: nadie se entera de un paciente que no atendió. El paciente verifica el dato nuevo antes de que se propague (código de un solo uso al número nuevo), así que lo que llega acá ya está confirmado. El evento no lleva nada clínico: solo cédula y contacto.
data: { patient: { identityType, identityNumber, phone?, email? }, updatedAt }.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Se envía a la aseguradora dueña del padrón con cada intento (verde o
rojo). La familia completa: identity.enrollment.completed,
identity.enrollment.revoked, identity.verification.completed y
identity.exception.recorded — todos con la misma forma de entrega y
firma que el resto de los webhooks. Nunca llevan datos clínicos:
cédula, resultado, código y quién operó.
| id | string |
| type | string |
| createdAt | string <date-time> |
object |
{- "id": "string",
- "type": "identity.verification.completed",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": {
- "identityNumber": "string",
- "policyNumber": "string",
- "attemptId": "string",
- "result": "verified",
- "authorizationCode": "string",
- "operatorOrgId": "string",
- "at": "2019-08-24T14:15:22Z"
}
}La familia de órdenes, toda dirigida y con la misma entrega firmada:
order.issued y order.item.review → a la aseguradora (lo emitido
contra ella y lo que espera a su auditor).order.item.authorized / order.item.rejected (con motivo),
order.fulfilled y result.available → al emisor, al instante.
Ningún evento lleva el contenido clínico del resultado: avisan que
está disponible y se lee por la API con la credencial propia.| id | string |
| type | string |
| createdAt | string <date-time> |
object |
{- "id": "string",
- "type": "order.item.authorized",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": {
- "orderId": "string",
- "itemId": "string",
- "studyCode": "string",
- "rejectReason": "string",
- "at": "2019-08-24T14:15:22Z"
}
}El laboratorio cargó el resultado: el médico tratante se entera al
instante y el paciente lo ve en su app a la par (y recibe un aviso
SMS sin datos clínicos si tiene cuenta). El evento solo referencia
(orderId, itemId, studyCode, abnormal, y — si la orden los
trajo — practitionerLicense y externalReference para rutear a
la bandeja del médico en tu sistema) — el contenido clínico se lee
por GET /orders con la credencial del emisor. La marca abnormal
permite priorizar sin esperar la lectura.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Representa a toda la familia de eventos de agendamiento —
appointment.booked, appointment.confirmed, appointment.cancelled,
appointment.completed y appointment.no_show — todos con el mismo
payload y SIEMPRE dirigidos a la clínica dueña de la agenda: así su
sistema (HIS, calendario, recordatorios) se sincroniza sin consultar.
El data lleva solo appointmentId, practitionerLicense,
patientIdentityNumber, startAt, endAt y status — el motivo de
consulta y las notas jamás viajan por webhook.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Representa a transcription.completed y transcription.failed,
SIEMPRE dirigidos a la clínica dueña y SIN contenido clínico: el
data lleva solo transcriptionId, status, durationSeconds y —
si se mandaron — practitionerLicense y externalReference para
rutear a la bandeja del médico en tu sistema. La nota se lee por
GET /transcriptions/{id} con tu credencial.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Representa a imaging.completed e imaging.failed, SIEMPRE dirigidos
a la organización dueña y SIN contenido clínico: el data lleva
analysisId, status, modality, la urgency sugerida (para
priorizar la bandeja del médico sin exponer hallazgos) y — si se
mandaron — practitionerLicense y externalReference. El informe se
lee por GET /imaging/analyses/{id} con tu credencial.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Registra una URL HTTPS de la organización para recibir eventos. La respuesta
incluye el secret (solo se muestra una vez) con el que se firma cada entrega.
Requiere scope webhooks:manage.
| url required | string <uri> URL HTTPS que recibirá los eventos por POST. |
| events required | Array of strings (WebhookEventType) non-empty Items Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| description | string |
{- "events": [
- "prescription.created"
], - "description": "string"
}{- "id": "we_01J8ZE2W7K",
- "events": [
- "prescription.created"
], - "description": "string",
- "secret": "string",
- "isActive": true,
- "createdAt": "2019-08-24T14:15:22Z"
}{- "data": [
- {
- "id": "we_01J8ZE2W7K",
- "events": [
- "prescription.created"
], - "description": "string",
- "secret": "string",
- "isActive": true,
- "createdAt": "2019-08-24T14:15:22Z"
}
]
}Lista los formatos de origen que la plataforma sabe interpretar. Cada entrada
identifica un adaptador (id) que traduce el modelo del sistema emisor al
modelo canónico de eMedic.
{- "data": [
- {
- "id": "fhir-r4",
- "name": "string",
- "description": "string"
}
]
}El formato del emisor no es su problema, es el nuestro. El hospital envía la receta tal como la produce su sistema (FHIR R4, el modelo del eMedic original, o el que se le construya) y la plataforma la transforma al modelo canónico.
La puerta final es invariable: el resultado de la transformación se valida contra
el mismo schema que POST /prescriptions. Un adaptador nunca puede colar una
receta que la API nativa rechazaría. Si la transformación falla o el resultado
no valida, la respuesta es 400 VALIDATION_ERROR con details señalando el
campo de origen.
El cuerpo es libre: su forma la define el adaptador elegido, no este contrato.
Solo organizaciones emisoras; una farmacia recibe 403.
| adapterId required | string Examples:
ID del adaptador (ver |
| Idempotency-Key | string <= 128 characters Clave única elegida por el cliente (UUID recomendado). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta original sin duplicar la operación. |
Payload en el formato de origen que el adaptador espera.
| property name* additional property | any |
{ }{- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z",
- "adapter": "string"
}El registro de remitentes es la identidad del médico en la ingesta por correo: la plataforma no puede validar a un desconocido, así que solo acepta recetas de direcciones dadas de alta por la propia clínica. Lo que el registro dice sobre el médico (nombre, matrícula) tiene prioridad sobre lo que la extracción lea del documento.
| emailAddress required | string <email> |
| practitionerName required | string |
| practitionerLicense required | string Número de registro/matrícula médica. |
| specialty | string |
{- "practitionerName": "string",
- "practitionerLicense": "string",
- "specialty": "string"
}{- "id": "snd_9f3c1a0b2d4e6f8a0b1c",
- "practitionerName": "string",
- "practitionerLicense": "string",
- "specialty": "string",
- "isActive": true,
- "createdAt": "2019-08-24T14:15:22Z"
}{- "data": [
- {
- "id": "snd_9f3c1a0b2d4e6f8a0b1c",
- "practitionerName": "string",
- "practitionerLicense": "string",
- "specialty": "string",
- "isActive": true,
- "createdAt": "2019-08-24T14:15:22Z"
}
]
}Baja lógica: el remitente deja de poder emitir, pero las recetas que ya envió conservan su trazabilidad.
| senderId required | string |
{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}Entrada para recetas que no vienen de una integración: el médico manda un PDF por correo y la clínica (o su gateway de correo) lo deposita aquí.
Puertas de confianza, en orden:
email con senderVerified: false — si el gateway no pudo validar
DKIM/SPF/DMARC, el ítem entra pero nunca se auto-aprueba: un correo falsificable
no puede emitir recetas a nombre de un médico.POST /intake/senders) no hay
médico identificable, así que tampoco hay auto-aprobación.La extracción estructurada corre en segundo plano; cuando pasa las puertas, la
receta se emite sola y prescriptionId queda apuntando a ella. Cuando no,
el ítem se devuelve al médico por correo (rebote) explicando qué corregir —
nunca queda esperando revisión humana de eMedic.
| source | string Default: "api" Enum: "email" "api" |
| senderAddress | string <email> Remitente del correo. Obligatorio si |
| senderVerified | boolean Resultado de DKIM/SPF/DMARC que reporta el gateway de correo. Solo un
|
| contentType | string Default: "text" Enum: "text" "json" |
| rawContent | string <= 200000 characters Cuerpo del correo o texto libre de la receta. |
Array of objects <= 5 items Documento original. Hasta 5 adjuntos, ~11 MB cada uno. |
{- "source": "email",
- "senderVerified": true,
- "contentType": "text",
- "rawContent": "string",
- "attachments": [
- {
- "filename": "string",
- "contentType": "application/pdf",
- "contentBase64": "string"
}
]
}{- "id": "ink_2c7d1e4f6a8b0c2d4e6f",
- "source": "email",
- "contentType": "text",
- "status": "pending_extraction",
- "senderVerified": true,
- "attachments": [
- {
- "id": "string",
- "filename": "string",
- "contentType": "string",
- "sizeBytes": 0
}
], - "proposal": { },
- "rawContent": "string",
- "receivedAt": "2019-08-24T14:15:22Z",
- "extractedAt": "2019-08-24T14:15:22Z",
- "reviewedAt": "2019-08-24T14:15:22Z",
- "reviewedBy": "string",
- "rejectReason": "string",
- "prescriptionId": "string"
}| status | string Enum: "pending_extraction" "pending_review" "approved" "rejected" |
| limit | integer [ 1 .. 100 ] Default: 50 |
| offset | integer >= 0 Default: 0 |
{- "data": [
- {
- "id": "ink_2c7d1e4f6a8b0c2d4e6f",
- "source": "email",
- "contentType": "text",
- "status": "pending_extraction",
- "senderVerified": true,
- "attachments": [
- {
- "id": "string",
- "filename": "string",
- "contentType": "string",
- "sizeBytes": 0
}
], - "proposal": { },
- "rawContent": "string",
- "receivedAt": "2019-08-24T14:15:22Z",
- "extractedAt": "2019-08-24T14:15:22Z",
- "reviewedAt": "2019-08-24T14:15:22Z",
- "reviewedBy": "string",
- "rejectReason": "string",
- "prescriptionId": "string"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0
}
}A diferencia del listado, incluye rawContent (el original completo).
| intakeId required | string ID del ítem de ingesta ( |
{- "id": "ink_2c7d1e4f6a8b0c2d4e6f",
- "source": "email",
- "contentType": "text",
- "status": "pending_extraction",
- "senderVerified": true,
- "attachments": [
- {
- "id": "string",
- "filename": "string",
- "contentType": "string",
- "sizeBytes": 0
}
], - "proposal": { },
- "rawContent": "string",
- "receivedAt": "2019-08-24T14:15:22Z",
- "extractedAt": "2019-08-24T14:15:22Z",
- "reviewedAt": "2019-08-24T14:15:22Z",
- "reviewedBy": "string",
- "rejectReason": "string",
- "prescriptionId": "string"
}Emite la receta a partir de la propuesta extraída. La clínica puede corregirla
enviando prescription con el borrador ya arreglado — quien aprueba es la
clínica emisora, no eMedic.
| intakeId required | string ID del ítem de ingesta ( |
| reviewedBy required | string Quién aprueba (queda en auditoría). |
object Borrador corregido; si se omite, se usa la propuesta extraída. |
{- "reviewedBy": "string",
- "prescription": { }
}{- "item": {
- "id": "ink_2c7d1e4f6a8b0c2d4e6f",
- "source": "email",
- "contentType": "text",
- "status": "pending_extraction",
- "senderVerified": true,
- "attachments": [
- {
- "id": "string",
- "filename": "string",
- "contentType": "string",
- "sizeBytes": 0
}
], - "proposal": { },
- "rawContent": "string",
- "receivedAt": "2019-08-24T14:15:22Z",
- "extractedAt": "2019-08-24T14:15:22Z",
- "reviewedAt": "2019-08-24T14:15:22Z",
- "reviewedBy": "string",
- "rejectReason": "string",
- "prescriptionId": "string"
}, - "prescription": {
- "id": "rx_01J8ZC4Q9M",
- "externalId": "string",
- "status": "active",
- "issuer": {
- "id": "org_01J8ZB0K2P",
- "name": "Clínica San Rafael"
}, - "patient": {
- "identityType": "cedula",
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "birthDate": "2019-08-24",
- "gender": "male",
- "address": "string",
- "phone": "+595981123456"
}, - "practitioner": {
- "name": "string",
- "licenseNumber": "string",
- "profession": "string",
- "specialty": "string"
}, - "diagnoses": [
- {
- "icd11Code": "CA40.0",
- "icd11Title": "Neumonía bacteriana",
- "sourceCode": "J18.9"
}
], - "medications": [
- {
- "name": "Amoxicilina 500 mg cápsulas",
- "atcCode": "J01CA04",
- "quantityPrescribed": 1,
- "unit": "cápsula",
- "dosageInstruction": {
- "text": "1 cápsula cada 8 horas por 7 días",
- "frequency": "string",
- "duration": "string"
}, - "substitutionAllowed": true,
- "id": "string",
- "status": "pending",
- "quantityDispensed": 0,
- "quantityAllowedTotal": 1,
- "quantityRemaining": 0
}
], - "signature": {
- "type": "digital_certificate",
- "value": "string",
- "contentType": "string",
- "certificate": "string",
- "signedAt": "2019-08-24T14:15:22Z"
}, - "notes": "string",
- "usesAllowed": 1,
- "createdAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "cancelledAt": "2019-08-24T14:15:22Z"
}
}| intakeId required | string ID del ítem de ingesta ( |
| reviewedBy required | string |
| reason required | string <= 1000 characters |
{- "reviewedBy": "string",
- "reason": "string"
}{- "id": "ink_2c7d1e4f6a8b0c2d4e6f",
- "source": "email",
- "contentType": "text",
- "status": "pending_extraction",
- "senderVerified": true,
- "attachments": [
- {
- "id": "string",
- "filename": "string",
- "contentType": "string",
- "sizeBytes": 0
}
], - "proposal": { },
- "rawContent": "string",
- "receivedAt": "2019-08-24T14:15:22Z",
- "extractedAt": "2019-08-24T14:15:22Z",
- "reviewedAt": "2019-08-24T14:15:22Z",
- "reviewedBy": "string",
- "rejectReason": "string",
- "prescriptionId": "string"
}Transparencia sobre lo que se va a facturar: la plataforma cobra por transacción (modelo de red tipo Surescripts) y esta ruta expone los mismos contadores y tarifas sobre los que se emite la factura. Cada línea incluye el precio que le aplica a la organización según su contrato; una línea con precio nulo es actividad medida sin cargo.
Cada organización ve únicamente el suyo: el organizationId sale de la
credencial, nunca de un parámetro, así que no hay forma de consultar el consumo
de otra organización. Sin from/to, el periodo es el mes corriente (UTC).
| from | string <date-time> Inicio del periodo (RFC 3339). Por defecto, el 1 del mes corriente. |
| to | string <date-time> Fin del periodo (RFC 3339). Por defecto, ahora. |
{- "data": [
- {
- "type": "prescription.routed",
- "count": 0,
- "unitAmountCents": 0,
- "amountCents": 0,
- "currency": "string"
}
], - "period": {
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z"
}
}Autoservicio del sandbox (sandbox.api.emedic.la): crea una organización de
prueba y devuelve una API key emk_test_... lista para usar, sin hablar con
nadie de eMedic. Los datos son ficticios y se reinician periódicamente.
Esta ruta solo existe en el sandbox. En producción las credenciales las emite el operador de la plataforma al firmar el contrato.
| organizationName required | string <= 200 characters |
| type required | string Enum: "clinic" "pharmacy" "laboratory" Rol que se quiere ensayar; define los permisos de la llave. |
{- "organizationName": "string",
- "type": "clinic"
}{- "organization": {
- "id": "string",
- "name": "string",
- "type": "string"
}, - "apiKey": "string",
- "scopes": [
- "string"
], - "environment": "sandbox"
}Verificación biométrica de asegurados en la recepción del prestador: padrón, enrolamiento con consentimiento, verificación con código de autorización y log inmutable para el antifraude de la aseguradora.
Se envía a la aseguradora dueña del padrón con cada intento (verde o
rojo). La familia completa: identity.enrollment.completed,
identity.enrollment.revoked, identity.verification.completed y
identity.exception.recorded — todos con la misma forma de entrega y
firma que el resto de los webhooks. Nunca llevan datos clínicos:
cédula, resultado, código y quién operó.
| id | string |
| type | string |
| createdAt | string <date-time> |
object |
{- "id": "string",
- "type": "identity.verification.completed",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": {
- "identityNumber": "string",
- "policyNumber": "string",
- "attemptId": "string",
- "result": "verified",
- "authorizationCode": "string",
- "operatorOrgId": "string",
- "at": "2019-08-24T14:15:22Z"
}
}Alta/actualización masiva del padrón. La clave de cada asegurado es
(aseguradora, cédula); una misma persona puede figurar en varios
padrones. Requiere el scope members:sync y una credencial de
organización tipo aseguradora — cada aseguradora solo escribe el suyo.
required | Array of objects (InsuredMemberInput) [ 1 .. 5000 ] items |
{- "members": [
- {
- "identityNumber": "string",
- "policyNumber": "string",
- "fullName": "string",
- "status": "active",
- "plan": "string",
- "phone": "string"
}
]
}{- "written": 0
}¿La cédula está en el padrón, con la póliza activa, y tiene registro
facial vigente? Es la primera llamada de la recepción. Un prestador
indica la aseguradora con insurerId; una credencial de aseguradora
consulta su propio padrón sin parámetro.
| identityNumber required | string |
| insurerId | string Aseguradora del paciente (obligatorio para prestadores). |
{- "found": true,
- "fullName": "string",
- "policyNumber": "string",
- "status": "active",
- "plan": "string",
- "enrolled": true
}En despliegues con proveedor de liveness (producción), TODO
enrolamiento y verificación exige una sesión: el navegador de la
recepción corre el desafío de cámara contra la sesión, y la única
imagen que se compara es la de auditoría de la sesión — el cliente
nunca elige qué foto se compara. Sin proveedor configurado (sandbox),
responde 501 y se manda image directa.
{- "sessionId": "string"
}Requiere identity:enroll. El consentimiento es obligatorio y queda
registrado con su texto exacto (dato biométrico = dato sensible). Un
re-enrolamiento revoca el registro anterior y ambos eventos llegan a
la aseguradora por webhook. Nunca se almacena la imagen: solo la
referencia opaca a la plantilla del motor biométrico. El asegurado
recibe un SMS de aviso sin ningún dato clínico.
| insurerId | string Aseguradora del paciente (prestadores). |
| identityNumber required | string |
| consentText required | string <= 2000 characters |
| image | string Captura base64 (solo despliegues sin liveness). |
| livenessSessionId | string Sesión de liveness completada (producción). |
| branchId | string |
{- "insurerId": "string",
- "identityNumber": "string",
- "consentText": "string",
- "image": "string",
- "livenessSessionId": "string",
- "branchId": "string"
}{- "enrollmentId": "string",
- "reEnrolled": true,
- "createdAt": "2019-08-24T14:15:22Z"
}El corazón del producto. Requiere identity:verify. En verde devuelve
el código de autorización (EMD-XXXX-XX) que el prestador adjunta
al claim, con su vencimiento según la política de la aseguradora. En
rojo informa el motivo y los reintentos de cámara restantes; agotados,
sugiere el camino de excepción (la atención nunca se bloquea). Todo
intento queda en el log inmutable y se mide como transacción
facturable atribuida a la aseguradora.
| insurerId | string |
| identityNumber required | string |
| image | string Captura base64 (solo despliegues sin liveness). |
| livenessSessionId | string |
| branchId | string |
{- "insurerId": "string",
- "identityNumber": "string",
- "image": "string",
- "livenessSessionId": "string",
- "branchId": "string"
}{- "result": "no_match",
- "message": "string",
- "attemptsLeft": 0,
- "suggestException": true
}El registro inmutable, paginado y filtrable — la misma lectura que
alimenta la consola web de la aseguradora. Requiere identity:read.
| result | string Enum: "verified" "no_match" "liveness_failed" "exception" |
| from | string <date-time> |
| to | string <date-time> |
| limit | integer Default: 50 |
| offset | integer Default: 0 |
{- "data": [
- {
- "id": "ver_1a2b3c4d5e",
- "identityNumber": "string",
- "policyNumber": "string",
- "result": "verified",
- "authorizationCode": "string",
- "authorizationExpiresAt": "2019-08-24T14:15:22Z",
- "similarity": 0,
- "exceptionReason": "not_enrolled",
- "exceptionNote": "string",
- "operatorOrgId": "string",
- "operatorBranchId": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0,
- "hasMore": true
}
}La aseguradora valida el código que el prestador adjuntó al claim:
existe, es suyo y está dentro de su vigencia. Un claim sin código
válido va a revisión. Requiere identity:read.
| authorizationCode required | string |
{- "valid": false,
- "reason": "not_found"
}Cuando la verificación no es posible (sin registro, urgencia, imposibilidad física, menor, sin conectividad), la recepción registra la excepción y la atención continúa. La aseguradora la ve en tiempo real y decide el pago; la tasa de excepciones por prestador es su detector antifraude.
| insurerId | string |
| identityNumber required | string |
| reason required | string Enum: "not_enrolled" "urgency" "physical_impossibility" "minor" "no_connectivity" "other" |
| note | string <= 1000 characters |
| branchId | string |
{- "insurerId": "string",
- "identityNumber": "string",
- "reason": "not_enrolled",
- "note": "string",
- "branchId": "string"
}{- "attemptId": "string"
}Verificadas, fallos y excepciones por prestador en el periodo (por
defecto, últimos 30 días). El prestador que esquiva la cámara se
destaca solo. Requiere identity:read; cada aseguradora ve solo su
actividad.
| from | string <date-time> |
| to | string <date-time> |
{- "data": [
- {
- "operatorOrgId": "string",
- "verified": 0,
- "failed": 0,
- "exceptions": 0
}
], - "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z"
}Liquidación viva: el claim nace presentado desde la verificación, la aseguradora lo adjudica claim por claim con SLA, gana firmeza y se liquida en cortes. La planilla mensual deja de existir.
Alta/actualización masiva de las prestaciones cubiertas, con arancel y
copago. Requiere claims:manage. Un ítem con isActive: false deja
de aceptar claims sin borrar su historia.
required | Array of objects (FeeScheduleItemInput) [ 1 .. 2000 ] items |
{- "items": [
- {
- "code": "CONS-COMUN",
- "name": "string",
- "amountCents": 0,
- "copayCents": 0,
- "currency": "PYG",
- "isActive": true
}
]
}{- "written": 0
}El prestador lo lee para registrar la prestación en un toque y saber
el copago exacto a cobrar en ventanilla. Requiere claims:submit (o
claims:manage para la propia aseguradora).
| insurerId | string Aseguradora (obligatorio para prestadores). |
{- "data": [
- {
- "code": "CONS-COMUN",
- "name": "string",
- "amountCents": 0,
- "copayCents": 0,
- "currency": "PYG",
- "isActive": true
}
]
}Requiere claims:submit. El claim referencia exactamente una
verificación: el código de autorización verde (authorizationCode) o
el intento de excepción (exceptionAttemptId) — nunca ambos. Reglas
del dominio: la prestación debe estar en el nomenclador vigente, el
código solo lo presenta el prestador que operó la verificación, y un
intento respalda a lo sumo un claim (409 al duplicar).
| insurerId required | string |
| serviceCode required | string |
| practitionerLicense | string <= 50 characters Matrícula del médico tratante. La matrícula es la identidad profesional de la red (como la cédula lo es del paciente): cada claim llega con ella — explícita, por |
| practitionerRef | string <= 120 characters Id del médico EN TU SISTEMA, resuelto por el directorio de prescriptores ( |
| authorizationCode | string |
| exceptionAttemptId | string |
{- "insurerId": "string",
- "serviceCode": "string",
- "practitionerLicense": "string",
- "practitionerRef": "string",
- "authorizationCode": "EMD-7K4P-2X",
- "exceptionAttemptId": "ver_1a2b3c4d5e"
}{- "id": "clm_1a2b3c4d5e",
- "insurerId": "string",
- "providerOrgId": "string",
- "practitionerLicense": "string",
- "identityNumber": "string",
- "policyNumber": "string",
- "serviceCode": "string",
- "serviceName": "string",
- "amountCents": 0,
- "copayCents": 0,
- "currency": "string",
- "authorizationCode": "string",
- "verificationResult": "verified",
- "status": "submitted",
- "objectionReason": "string",
- "submittedAt": "2019-08-24T14:15:22Z",
- "adjudicatedAt": "2019-08-24T14:15:22Z",
- "settlementId": "string",
- "settledAt": "2019-08-24T14:15:22Z"
}El prestador ve los claims que presentó; la aseguradora, los presentados contra ella. Filtrable por estado.
| status | string Enum: "submitted" "approved" "objected" "firm" "settled" |
| limit | integer Default: 50 |
| offset | integer Default: 0 |
{- "data": [
- {
- "id": "clm_1a2b3c4d5e",
- "insurerId": "string",
- "providerOrgId": "string",
- "practitionerLicense": "string",
- "identityNumber": "string",
- "policyNumber": "string",
- "serviceCode": "string",
- "serviceName": "string",
- "amountCents": 0,
- "copayCents": 0,
- "currency": "string",
- "authorizationCode": "string",
- "verificationResult": "verified",
- "status": "submitted",
- "objectionReason": "string",
- "submittedAt": "2019-08-24T14:15:22Z",
- "adjudicatedAt": "2019-08-24T14:15:22Z",
- "settlementId": "string",
- "settledAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0,
- "hasMore": true
}
}Totales por estado (presentado, aprobado, objetado, firme,
liquidado): lo que reemplaza a la planilla mensual. Requiere
claims:submit.
{- "submitted": {
- "count": 0,
- "totalCents": 0
}, - "approved": {
- "count": 0,
- "totalCents": 0
}, - "objected": {
- "count": 0,
- "totalCents": 0
}, - "firm": {
- "count": 0,
- "totalCents": 0
}, - "settled": {
- "count": 0,
- "totalCents": 0
}, - "currency": "string"
}La aseguradora decide claim por claim dentro del SLA del convenio.
La objeción lleva su motivo y le llega al prestador por webhook al
instante — no 60 días después. Requiere claims:manage.
| claimId required | string |
| decision required | string Enum: "approve" "object" |
| objectionReason | string Obligatorio al objetar. |
{- "decision": "approve",
- "objectionReason": "string"
}{- "id": "clm_1a2b3c4d5e",
- "insurerId": "string",
- "providerOrgId": "string",
- "practitionerLicense": "string",
- "identityNumber": "string",
- "policyNumber": "string",
- "serviceCode": "string",
- "serviceName": "string",
- "amountCents": 0,
- "copayCents": 0,
- "currency": "string",
- "authorizationCode": "string",
- "verificationResult": "verified",
- "status": "submitted",
- "objectionReason": "string",
- "submittedAt": "2019-08-24T14:15:22Z",
- "adjudicatedAt": "2019-08-24T14:15:22Z",
- "settlementId": "string",
- "settledAt": "2019-08-24T14:15:22Z"
}Marca liquidados todos los claims firmes y devuelve las líneas por
prestador: a quién transferir cuánto. El corte es atómico — dos
cortes concurrentes no liquidan dos veces el mismo claim. Cada
prestador recibe por webhook SOLO su parte. Requiere claims:manage.
{- "settlementId": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "claimCount": 0,
- "totalCents": 0,
- "currency": "string",
- "lines": [
- {
- "providerOrgId": "string",
- "claimCount": 0,
- "totalCents": 0
}
]
}Anticipo del banco socio, SIEMPRE opcional: el prestador que lo activa cede sus claims firmes y cobra hoy con un descuento explícito; el que no, cobra por corte sin costo. eMedic es el registro único de cesiones y el árbitro de la instrucción de dispersión — la plata nunca pasa por la plataforma.
off = cobro por corte, sin costo. manual = elijo qué claims
anticipar. auto = todo claim firme se cede solo tras el barrido de
firmeza. Reversible en cualquier momento.
| mode required | string Enum: "off" "manual" "auto" |
{- "mode": "off"
}{- "mode": "off",
- "feeBps": 0
}Cada línea trae monto, descuento y neto a recibir hoy — el costo del
anticipo jamás se oculta. Requiere claims:submit.
{- "data": [
- {
- "claimId": "string",
- "serviceName": "string",
- "amountCents": 0,
- "feeCents": 0,
- "netCents": 0,
- "currency": "string",
- "firmAt": "2019-08-24T14:15:22Z"
}
], - "feeBps": 0
}Reglas del registro único: solo un claim FIRME propio y sin cesión previa (409 al duplicar). La cesión avisa al banco (con el paquete de evidencia) y a la aseguradora (ese claim se paga al banco en el corte).
| claimId required | string |
{- "claimId": "string"
}{- "id": "ces_1a2b3c4d5e",
- "claimId": "string",
- "insurerId": "string",
- "providerOrgId": "string",
- "amountCents": 0,
- "feeCents": 0,
- "netCents": 0,
- "currency": "string",
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "paidAt": "2019-08-24T14:15:22Z"
}| status | string Enum: "created" "paid" |
| limit | integer Default: 50 |
| offset | integer Default: 0 |
{- "data": [
- {
- "id": "ces_1a2b3c4d5e",
- "claimId": "string",
- "insurerId": "string",
- "providerOrgId": "string",
- "amountCents": 0,
- "feeCents": 0,
- "netCents": 0,
- "currency": "string",
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "paidAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0,
- "hasMore": true
}
}Atómico: una cesión se paga UNA vez y solo por su banco. El prestador
recibe advance.paid por webhook. Requiere financing:manage.
| cessionId required | string |
{- "id": "ces_1a2b3c4d5e",
- "claimId": "string",
- "insurerId": "string",
- "providerOrgId": "string",
- "amountCents": 0,
- "feeCents": 0,
- "netCents": 0,
- "currency": "string",
- "status": "created",
- "createdAt": "2019-08-24T14:15:22Z",
- "paidAt": "2019-08-24T14:15:22Z"
}La pieza autoritativa que el banco recaudador ejecuta: a quién
transferir cuánto — lo cedido al banco, el resto a cada prestador.
La leen el banco (financing:manage) y la aseguradora
(claims:manage).
| settlementId required | string |
{- "settlementId": "string",
- "lines": [
- {
- "payeeOrgId": "string",
- "payeeType": "provider",
- "claimCount": 0,
- "totalCents": 0
}
]
}Órdenes de estudios con visación instantánea por ítem: el médico emite contra el catálogo de la plataforma, el motor de reglas del convenio decide cada estudio en un segundo (autorizado, rechazado con motivo, o a la cola del auditor), el laboratorio la realiza una sola vez y el resultado vuelve al médico y al paciente en tiempo real. El laboratorio nunca ve el diagnóstico ni las notas del médico.
La familia de órdenes, toda dirigida y con la misma entrega firmada:
order.issued y order.item.review → a la aseguradora (lo emitido
contra ella y lo que espera a su auditor).order.item.authorized / order.item.rejected (con motivo),
order.fulfilled y result.available → al emisor, al instante.
Ningún evento lleva el contenido clínico del resultado: avisan que
está disponible y se lee por la API con la credencial propia.| id | string |
| type | string |
| createdAt | string <date-time> |
object |
{- "id": "string",
- "type": "order.item.authorized",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": {
- "orderId": "string",
- "itemId": "string",
- "studyCode": "string",
- "rejectReason": "string",
- "at": "2019-08-24T14:15:22Z"
}
}El laboratorio cargó el resultado: el médico tratante se entera al
instante y el paciente lo ve en su app a la par (y recibe un aviso
SMS sin datos clínicos si tiene cuenta). El evento solo referencia
(orderId, itemId, studyCode, abnormal, y — si la orden los
trajo — practitionerLicense y externalReference para rutear a
la bandeja del médico en tu sistema) — el contenido clínico se lee
por GET /orders con la credencial del emisor. La marca abnormal
permite priorizar sin esperar la lectura.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}El catálogo único contra el que se emite toda orden: código, nombre,
categoría, tipo de muestra y prerrequisitos legibles para el paciente
("Ayuno de 8 horas"). Cualquier credencial con un scope de órdenes
(orders:submit, orders:manage u orders:fulfill) puede leerlo.
| q | string >= 2 characters Búsqueda por texto (sin distinción de tildes). |
{- "data": [
- {
- "code": "CBC",
- "name": "Hemograma completo",
- "category": "Hematología",
- "sampleType": "string",
- "prerequisites": [
- "Ayuno de 8 horas"
], - "fasting": true
}
]
}Alta/actualización masiva de las reglas del convenio por código de
estudio: cubierto o no, si requiere auditoría médica y el tope anual
por asegurado. Con estas reglas el motor decide la mayoría de las
órdenes en un segundo. Requiere orders:manage y credencial de
aseguradora.
required | Array of objects (CoverageRuleInput) [ 1 .. 2000 ] items |
{- "rules": [
- {
- "studyCode": "string",
- "covered": true,
- "requiresReview": false,
- "annualLimit": null
}
]
}{- "written": 0
}El emisor las lee para anticipar el veredicto antes de emitir
(orders:submit, con insurerId); la aseguradora lee las suyas
(orders:manage).
| insurerId | string Aseguradora (obligatorio para emisores). |
{- "data": [
- {
- "studyCode": "string",
- "covered": true,
- "requiresReview": false,
- "annualLimit": null
}
]
}Requiere orders:submit. El motor decide CADA estudio en el momento
con las reglas del convenio: authorized en un segundo, rejected
con motivo claro, o pending_review en la cola del auditor. Un
estudio no cubierto no bloquea al resto de la orden. La respuesta ya
trae el veredicto de cada ítem — eso reemplaza a la foto de la orden
por WhatsApp y a los días de espera.
| insurerId required | string |
| patientIdentityNumber required | string Cédula del paciente. |
| patientFullName required | string |
| studyCodes required | Array of strings [ 1 .. 20 ] items |
Array of objects <= 10 items CIE-11 del emisor. Lo ven el paciente, el emisor y la aseguradora — el laboratorio JAMÁS. | |
| notes | string <= 2000 characters Notas del médico. Nunca llegan al laboratorio. |
| practitionerLicense | string <= 50 characters Matrícula del prescriptor. La matrícula es la identidad profesional de la red: cada acto llega con ella — mandala explícita, o mandá |
| practitionerRef | string <= 120 characters Id del médico EN TU SISTEMA (legajo, id de usuario), resuelto a matrícula por el directorio de prescriptores ( |
| externalReference | string <= 120 characters Id de la orden EN TU SISTEMA (texto libre, patrón placer-number). Va y vuelve intacto en respuestas y webhooks del emisor; ninguna otra audiencia lo ve. |
{- "insurerId": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "studyCodes": [
- "CBC",
- "GLU",
- "TSH"
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string",
- "practitionerLicense": "string",
- "practitionerRef": "string",
- "externalReference": "string"
}{- "id": "ord_1a2b3c4d5e6f7a8b9c0d",
- "insurerId": "string",
- "issuerOrgId": "string",
- "practitionerLicense": "string",
- "externalReference": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "issuedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "items": [
- {
- "id": "oit_1a2b3c4d5e6f7a8b",
- "studyCode": "string",
- "studyName": "string",
- "status": "pending_review",
- "rejectReason": "string",
- "fulfilledAt": "2019-08-24T14:15:22Z",
- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultAttachmentRef": "string",
- "resultAbnormal": true,
- "resultAt": "2019-08-24T14:15:22Z"
}
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string"
}El emisor ve las órdenes que emitió, con resultados; la aseguradora,
las emitidas contra ella. Filtrable por estado de ítem — la
aseguradora usa itemStatus=pending_review como su cola de auditoría.
| itemStatus | string Enum: "pending_review" "authorized" "rejected" "fulfilled" |
| limit | integer Default: 30 |
| offset | integer Default: 0 |
{- "data": [
- {
- "id": "ord_1a2b3c4d5e6f7a8b9c0d",
- "insurerId": "string",
- "issuerOrgId": "string",
- "practitionerLicense": "string",
- "externalReference": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "issuedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "items": [
- {
- "id": "oit_1a2b3c4d5e6f7a8b",
- "studyCode": "string",
- "studyName": "string",
- "status": "pending_review",
- "rejectReason": "string",
- "fulfilledAt": "2019-08-24T14:15:22Z",
- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultAttachmentRef": "string",
- "resultAbnormal": true,
- "resultAt": "2019-08-24T14:15:22Z"
}
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0
}
}Requiere orders:fulfill. El paciente llega solo con su cédula: el
laboratorio ve sus órdenes vigentes con ítems autorizados y los
prerrequisitos de cada estudio. La vista es la audiencia lab:
SIN diagnósticos, SIN notas del médico y sin resultados de otros.
| identityNumber required | string |
{- "data": [
- {
- "id": "ord_1a2b3c4d5e6f7a8b9c0d",
- "insurerId": "string",
- "issuerOrgId": "string",
- "practitionerLicense": "string",
- "externalReference": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "issuedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "items": [
- {
- "id": "oit_1a2b3c4d5e6f7a8b",
- "studyCode": "string",
- "studyName": "string",
- "status": "pending_review",
- "rejectReason": "string",
- "fulfilledAt": "2019-08-24T14:15:22Z",
- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultAttachmentRef": "string",
- "resultAbnormal": true,
- "resultAt": "2019-08-24T14:15:22Z"
}
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string"
}
]
}Requiere orders:manage. Solo aplica a ítems pending_review; el
emisor recibe order.item.authorized o order.item.rejected al
instante, y el paciente lo ve reflejado en su app. Un rechazo lleva
su motivo, siempre.
| orderId required | string |
| itemId required | string |
| decision required | string Enum: "authorize" "reject" |
| rejectReason | string Obligatorio al rechazar. |
{- "decision": "authorize",
- "rejectReason": "string"
}{- "id": "ord_1a2b3c4d5e6f7a8b9c0d",
- "insurerId": "string",
- "issuerOrgId": "string",
- "practitionerLicense": "string",
- "externalReference": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "issuedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "items": [
- {
- "id": "oit_1a2b3c4d5e6f7a8b",
- "studyCode": "string",
- "studyName": "string",
- "status": "pending_review",
- "rejectReason": "string",
- "fulfilledAt": "2019-08-24T14:15:22Z",
- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultAttachmentRef": "string",
- "resultAbnormal": true,
- "resultAt": "2019-08-24T14:15:22Z"
}
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string"
}Requiere orders:fulfill. Single-use atómico: el primer laboratorio
que lo marca se lo queda; un segundo intento — propio o de otro
laboratorio — recibe 409. Una orden vencida no se realiza
(ORDER_EXPIRED).
| orderId required | string |
| itemId required | string |
{- "id": "ord_1a2b3c4d5e6f7a8b9c0d",
- "insurerId": "string",
- "issuerOrgId": "string",
- "practitionerLicense": "string",
- "externalReference": "string",
- "patientIdentityNumber": "string",
- "patientFullName": "string",
- "issuedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z",
- "items": [
- {
- "id": "oit_1a2b3c4d5e6f7a8b",
- "studyCode": "string",
- "studyName": "string",
- "status": "pending_review",
- "rejectReason": "string",
- "fulfilledAt": "2019-08-24T14:15:22Z",
- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultAttachmentRef": "string",
- "resultAbnormal": true,
- "resultAt": "2019-08-24T14:15:22Z"
}
], - "diagnoses": [
- {
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "notes": "string"
}Requiere orders:fulfill y solo lo acepta el laboratorio que realizó
el ítem. El resultado viaja en tiempo real y a la par: el emisor
recibe result.available y el paciente lo ve en su app — nadie más.
| orderId required | string |
| itemId required | string |
| resultText | string <= 10000 characters Resumen u observaciones en texto (opcional). |
Array of objects (ResultValueInput) <= 100 items Valores estructurados del informe. | |
| resultPdfBase64 | string El informe ORIGINAL en PDF (base64, ~5 MB máx). El dato estructurado convive con el documento, jamás lo reemplaza: emisor y paciente lo abren con su botón. |
| resultAttachmentRef | string Referencia externa al documento (alternativa al PDF). |
| resultAbnormal | boolean Fuera de rango según el laboratorio: el médico tratante lo ve primero en su bandeja y el evento lo lleva como |
{- "resultText": "string",
- "resultValues": [
- {
- "analyteCode": "string",
- "name": "Hemoglobina",
- "value": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0,
- "outOfRange": true
}
], - "resultPdfBase64": "string",
- "resultAttachmentRef": "string",
- "resultAbnormal": true
}{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}Sugerencias de analitos con unidad y rango de referencia GENERALES, para pre-llenar el LIS o el mostrador. El rango autoritativo es siempre el del informe del laboratorio que procesó la muestra. Cualquier scope de órdenes puede leerlas.
| studyCode required | string |
{- "data": [
- {
- "code": "string",
- "name": "string",
- "unit": "string",
- "refLow": 0,
- "refHigh": 0
}
]
}El botón "Ver informe original": el dato estructurado convive con el
documento, jamás lo reemplaza. Lo lee el emisor de la orden
(orders:submit) o la aseguradora del convenio (orders:manage);
una organización ajena recibe 404.
| orderId required | string |
| itemId required | string |
{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}Agenda por prescriptor y turnos: la clínica define franjas, duración y colchón; la disponibilidad se calcula sola; la reserva es atómica (dos pedidos por el mismo hueco jamás ganan los dos) y cada cambio de estado sale como webhook dirigido a la clínica dueña. El motivo de consulta nunca viaja en los eventos.
Representa a toda la familia de eventos de agendamiento —
appointment.booked, appointment.confirmed, appointment.cancelled,
appointment.completed y appointment.no_show — todos con el mismo
payload y SIEMPRE dirigidos a la clínica dueña de la agenda: así su
sistema (HIS, calendario, recordatorios) se sincroniza sin consultar.
El data lleva solo appointmentId, practitionerLicense,
patientIdentityNumber, startAt, endAt y status — el motivo de
consulta y las notas jamás viajan por webhook.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Franjas de atención en hora local de la agenda (zona IANA), duración
del turno, colchón entre turnos y tope diario. La disponibilidad se
calcula a partir de esto: no hay calendarios que sincronizar. Solo
organizaciones que atienden pacientes (clínicas, laboratorios).
Requiere scheduling:manage.
| license required | string Matrícula del prescriptor (la misma clave que órdenes y claims). |
| timezone required | string Zona horaria IANA de las franjas. |
| slotMinutes required | integer [ 5 .. 240 ] |
| bufferMinutes required | integer [ 0 .. 120 ] |
| maxPerDay | integer or null [ 1 .. 200 ] |
required | Array of objects (WorkingDay) |
{- "timezone": "America/Asuncion",
- "slotMinutes": 5,
- "bufferMinutes": 120,
- "maxPerDay": 1,
- "workingDays": [
- {
- "dayOfWeek": 6,
- "intervals": [
- {
- "start": "08:00",
- "end": "12:00"
}
]
}
]
}{- "timezone": "America/Asuncion",
- "slotMinutes": 5,
- "bufferMinutes": 120,
- "maxPerDay": 1,
- "workingDays": [
- {
- "dayOfWeek": 6,
- "intervals": [
- {
- "start": "08:00",
- "end": "12:00"
}
]
}
], - "practitionerLicense": "string"
}Requiere scheduling:read o scheduling:manage.
| license required | string Matrícula del prescriptor (la misma clave que órdenes y claims). |
{- "timezone": "America/Asuncion",
- "slotMinutes": 5,
- "bufferMinutes": 120,
- "maxPerDay": 1,
- "workingDays": [
- {
- "dayOfWeek": 6,
- "intervals": [
- {
- "start": "08:00",
- "end": "12:00"
}
]
}
], - "practitionerLicense": "string"
}Los huecos del día según la agenda, descontando los turnos vivos, el
colchón, el tope diario y lo ya pasado. Los horarios vuelven como
instantes UTC. Requiere scheduling:read o scheduling:manage.
| license required | string Matrícula del prescriptor (la misma clave que órdenes y claims). |
| date required | string <date> Día a consultar (YYYY-MM-DD, calendario de la agenda). |
{- "date": "2019-08-24",
- "timezone": "string",
- "slotMinutes": 0,
- "practitionerLicense": "string",
- "slots": [
- {
- "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z"
}
]
}Reserva atómica: dos pedidos por el mismo hueco jamás ganan los dos —
el perdedor recibe 409 CONFLICT con la franja ocupada (nunca con los
datos del otro paciente). Sin endAt, el turno dura slotMinutes de
la agenda (o 30 minutos). El evento appointment.booked sale dirigido
a tu organización. Requiere scheduling:manage.
| practitionerLicense required | string |
| practitionerName | string |
required | object (AppointmentPatient) |
| startAt required | string <date-time> Instante UTC (ISO 8601 con zona). |
| endAt | string <date-time> Opcional; sin esto dura |
| reason | string <= 2000 characters Motivo de consulta; jamás sale de tu organización. |
| notes | string <= 2000 characters |
{- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "reason": "string",
- "notes": "string"
}{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}Solo los turnos de tu organización, ordenados por inicio. Requiere scheduling:read o scheduling:manage.
| practitionerLicense | string |
| from | string <date-time> |
| to | string <date-time> |
| status | string (AppointmentStatus) Enum: "scheduled" "confirmed" "completed" "cancelled" "no_show" |
| limit | integer [ 1 .. 100 ] Default: 20 |
| offset | integer >= 0 Default: 0 |
{- "data": [
- {
- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0
}
}Requiere scheduling:read o scheduling:manage.
| appointmentId required | string ID del turno ( |
{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}scheduled → confirmed; publica appointment.confirmed. Requiere scheduling:manage.
| appointmentId required | string ID del turno ( |
{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}El hueco vuelve a estar libre al instante; publica appointment.cancelled. Un turno cancelado es terminal. Requiere scheduling:manage.
| appointmentId required | string ID del turno ( |
| reason | string <= 500 characters |
{- "reason": "string"
}{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}Publica appointment.completed. Requiere scheduling:manage.
| appointmentId required | string ID del turno ( |
{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}Publica appointment.no_show. Requiere scheduling:manage.
| appointmentId required | string ID del turno ( |
{- "id": "apt_1f2e3d4c5b6a79881726",
- "practitionerLicense": "string",
- "practitionerName": "string",
- "patient": {
- "identityNumber": "string",
- "firstName": "string",
- "lastName": "string",
- "phone": "string"
}, - "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "status": "scheduled",
- "reason": "string",
- "notes": "string",
- "cancelReason": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}Transcripción médica: el médico dicta y la plataforma devuelve la transcripción fiel, una nota clínica estructurada (con diagnósticos codificables a CIE-11) y, si se dictaron medicamentos, un borrador de receta que el médico confirma y firma. Asíncrono, con webhook sin contenido clínico. Nada se inventa: lo dudoso queda declarado en issues.
Representa a transcription.completed y transcription.failed,
SIEMPRE dirigidos a la clínica dueña y SIN contenido clínico: el
data lleva solo transcriptionId, status, durationSeconds y —
si se mandaron — practitionerLicense y externalReference para
rutear a la bandeja del médico en tu sistema. La nota se lee por
GET /transcriptions/{id} con tu credencial.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}El médico dicta (o se graba la consulta) y la plataforma devuelve la
transcripción fiel más una nota clínica estructurada y, si se dictaron
medicamentos, un borrador de receta. El proceso es asíncrono: esto
devuelve 202 con estado pending; el resultado se consulta por id o
llega el webhook transcription.completed (sin contenido clínico).
El borrador jamás se emite solo: la receta la confirma y firma el
médico por los canales de siempre. Audio hasta 20 MB en base64.
Requiere transcription:manage (solo clínicas).
| audioBase64 required | string El audio en base64 (hasta ~20 MB de audio). |
| contentType required | string Enum: "audio/mpeg" "audio/mp3" "audio/mp4" "audio/x-m4a" "audio/wav" "audio/x-wav" "audio/webm" "audio/ogg" "audio/flac" Tipo del audio. |
| language | string Idioma del dictado (default es). |
| practitionerLicense | string Matrícula del médico que dicta (rutea la nota en tu sistema). |
| patientIdentityNumber | string Cédula del paciente, para ligar la nota a su historia. |
| externalReference | string <= 200 characters Referencia de la consulta en tu sistema; vuelve en el webhook. |
{- "audioBase64": "string",
- "contentType": "audio/mpeg",
- "language": "es",
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string"
}{- "id": "trx_9f8e7d6c5b4a32101234",
- "status": "pending",
- "language": "string",
- "audioContentType": "string",
- "audioSizeBytes": 0,
- "durationSeconds": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "transcript": "string",
- "note": {
- "chiefComplaint": "string",
- "history": "string",
- "examination": "string",
- "diagnoses": [
- {
- "sourceTitle": "string",
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "plan": "string",
- "instructions": "string",
- "followUp": "string"
}, - "prescriptionDraft": {
- "medications": [
- {
- "name": "string",
- "quantityPrescribed": 0,
- "unit": "string",
- "dosageInstruction": {
- "text": "string",
- "frequency": "string",
- "duration": "string"
}
}
]
}, - "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}Solo las de tu organización. Requiere transcription:manage.
| status | string Enum: "pending" "processing" "completed" "failed" |
| practitionerLicense | string |
| limit | integer [ 1 .. 100 ] Default: 20 |
| offset | integer >= 0 Default: 0 |
{- "data": [
- {
- "id": "trx_9f8e7d6c5b4a32101234",
- "status": "pending",
- "language": "string",
- "audioContentType": "string",
- "audioSizeBytes": 0,
- "durationSeconds": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "transcript": "string",
- "note": {
- "chiefComplaint": "string",
- "history": "string",
- "examination": "string",
- "diagnoses": [
- {
- "sourceTitle": "string",
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "plan": "string",
- "instructions": "string",
- "followUp": "string"
}, - "prescriptionDraft": {
- "medications": [
- {
- "name": "string",
- "quantityPrescribed": 0,
- "unit": "string",
- "dosageInstruction": {
- "text": "string",
- "frequency": "string",
- "duration": "string"
}
}
]
}, - "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0
}
}Transcripción fiel, nota clínica, borrador de receta y dudas declaradas (issues). Requiere transcription:manage.
| transcriptionId required | string ID de la transcripción ( |
{- "id": "trx_9f8e7d6c5b4a32101234",
- "status": "pending",
- "language": "string",
- "audioContentType": "string",
- "audioSizeBytes": 0,
- "durationSeconds": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "transcript": "string",
- "note": {
- "chiefComplaint": "string",
- "history": "string",
- "examination": "string",
- "diagnoses": [
- {
- "sourceTitle": "string",
- "icd11Code": "string",
- "icd11Title": "string"
}
], - "plan": "string",
- "instructions": "string",
- "followUp": "string"
}, - "prescriptionDraft": {
- "medications": [
- {
- "name": "string",
- "quantityPrescribed": 0,
- "unit": "string",
- "dosageInstruction": {
- "text": "string",
- "frequency": "string",
- "duration": "string"
}
}
]
}, - "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}El audio tal como se mandó, para auditoría de la clínica dueña. Requiere transcription:manage.
| transcriptionId required | string ID de la transcripción ( |
{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}IA de imágenes (radiografías, ECG y más) como apoyo a la decisión clínica: informe preliminar con hallazgos, impresión, urgencia sugerida conservadora y limitaciones declaradas. Todo informe lleva un disclaimer fijo — no es diagnóstico, el médico que mira la imagen decide — y ninguna acción clínica se dispara sola.
Representa a imaging.completed e imaging.failed, SIEMPRE dirigidos
a la organización dueña y SIN contenido clínico: el data lleva
analysisId, status, modality, la urgency sugerida (para
priorizar la bandeja del médico sin exponer hallazgos) y — si se
mandaron — practitionerLicense y externalReference. El informe se
lee por GET /imaging/analyses/{id} con tu credencial.
| id required | string ID del evento (estable entre reintentos). |
| type required | string (WebhookEventType) Enum: "prescription.created" "prescription.dispensed" "prescription.fully_dispensed" "prescription.cancelled" "prescription.expired" "patient.contact_updated" "identity.enrollment.completed" "identity.enrollment.revoked" "identity.verification.completed" "identity.exception.recorded" "claim.submitted" "claim.approved" "claim.objected" "claim.firm" "claim.ceded" "advance.paid" "settlement.created" "order.issued" "order.item.authorized" "order.item.rejected" "order.item.review" "order.fulfilled" "result.available" "appointment.booked" "appointment.confirmed" "appointment.cancelled" "appointment.completed" "appointment.no_show" "transcription.completed" "transcription.failed" "imaging.completed" "imaging.failed" |
| createdAt required | string <date-time> |
| data required | object Para |
{- "id": "evt_01J8ZF9X1Q",
- "type": "prescription.created",
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { }
}Radiografías, ECG y otras imágenes (PNG/JPEG/WebP/GIF, hasta 5 MB)
vuelven como un informe preliminar de apoyo a la decisión clínica:
hallazgos, impresión preliminar, urgencia sugerida (conservadora) y
limitaciones declaradas. Todo informe lleva un disclaimer fijo:
no es diagnóstico — el médico que mira la imagen decide. Asíncrono:
202 pending y el webhook imaging.completed (con la urgencia para
priorizar bandejas, sin ningún hallazgo). Requiere imaging:manage
(clínicas y laboratorios).
| imageBase64 required | string La imagen en base64 (hasta 5 MB). |
| contentType required | string Enum: "image/png" "image/jpeg" "image/webp" "image/gif" |
| modality required | string Enum: "xray" "ecg" "ct" "mri" "ultrasound" "other" |
| bodyPart | string <= 200 characters Región anatómica (p. ej. "tórax PA"). |
| clinicalContext | string <= 2000 characters Contexto clínico que el médico aporta; jamás sale de tu organización. |
| practitionerLicense | string Matrícula del médico (rutea el informe en tu sistema). |
| patientIdentityNumber | string |
| externalReference | string <= 200 characters Referencia del estudio en tu sistema; vuelve en el webhook. |
{- "imageBase64": "string",
- "contentType": "image/png",
- "modality": "xray",
- "bodyPart": "string",
- "clinicalContext": "string",
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string"
}{- "id": "img_4a3b2c1d0e9f87651234",
- "status": "pending",
- "modality": "xray",
- "bodyPart": "string",
- "clinicalContext": "string",
- "imageContentType": "string",
- "imageSizeBytes": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "report": {
- "technicalQuality": "string",
- "findings": [
- {
- "description": "string",
- "location": "string",
- "severity": "normal"
}
], - "impression": "string",
- "urgency": "routine",
- "limitations": [
- "string"
]
}, - "disclaimer": "string",
- "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}Solo los de tu organización. Requiere imaging:manage.
| status | string Enum: "pending" "processing" "completed" "failed" |
| practitionerLicense | string |
| limit | integer [ 1 .. 100 ] Default: 20 |
| offset | integer >= 0 Default: 0 |
{- "data": [
- {
- "id": "img_4a3b2c1d0e9f87651234",
- "status": "pending",
- "modality": "xray",
- "bodyPart": "string",
- "clinicalContext": "string",
- "imageContentType": "string",
- "imageSizeBytes": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "report": {
- "technicalQuality": "string",
- "findings": [
- {
- "description": "string",
- "location": "string",
- "severity": "normal"
}
], - "impression": "string",
- "urgency": "routine",
- "limitations": [
- "string"
]
}, - "disclaimer": "string",
- "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "limit": 0,
- "offset": 0
}
}Hallazgos, impresión preliminar, urgencia, limitaciones y el disclaimer de apoyo a la decisión. Requiere imaging:manage.
| analysisId required | string ID del análisis ( |
{- "id": "img_4a3b2c1d0e9f87651234",
- "status": "pending",
- "modality": "xray",
- "bodyPart": "string",
- "clinicalContext": "string",
- "imageContentType": "string",
- "imageSizeBytes": 0,
- "practitionerLicense": "string",
- "patientIdentityNumber": "string",
- "externalReference": "string",
- "report": {
- "technicalQuality": "string",
- "findings": [
- {
- "description": "string",
- "location": "string",
- "severity": "normal"
}
], - "impression": "string",
- "urgency": "routine",
- "limitations": [
- "string"
]
}, - "disclaimer": "string",
- "issues": [
- "string"
], - "error": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}La imagen tal como se mandó, para auditoría de la organización dueña. Requiere imaging:manage.
| analysisId required | string ID del análisis ( |
{- "error": {
- "code": "UNAUTHORIZED",
- "message": "string",
- "details": [
- {
- "field": "string",
- "issue": "string"
}
]
}
}La matrícula es la identidad profesional de la red. Si tu sistema no
tiene un campo de matrícula, declarás tu plantel UNA vez acá — el id
interno de cada médico (externalRef) y su matrícula — y desde ahí
emitís órdenes y presentás claims con practitionerRef: cero
cambios en tu HIS. Upsert por matrícula: re-declarar actualiza
nombre y ref sin duplicar ni pisar la verificación del operador.
required | Array of objects [ 1 .. 1000 ] items |
{- "practitioners": [
- {
- "externalRef": "string",
- "license": "string",
- "name": "string"
}
]
}{- "data": [
- {
- "id": "prc_1a2b3c4d5e6f7a8b",
- "externalRef": "string",
- "license": "string",
- "name": "string",
- "verified": true
}
]
}