AnpherosAnpheros PlatformDevelopers

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Cómo almacenar expedientes médicos usando FHIR R4

Tutorial: crear un Paciente, una Observación de presión arterial y una Condición, usar una transacción, buscar, actualizar con historial y leer procedencia — cada solicitud con curl y la respuesta real, en el sandbox gratuito.

Este tutorial almacena un pequeño registro médico como recursos HL7 FHIR R4: un Patient, una Observation de presión arterial y un diagnóstico como Condition, luego un paciente y una medición juntos en una transacción. Los busca, actualiza el diagnóstico sin perder la versión anterior y lee quién escribió qué. Cada solicitud es curl plano contra el sandbox gratuito de Anpheros, y cada respuesta mostrada es lo que la API devuelve.

Si es nuevo en FHIR, lea primero Plataforma FHIR para conocer los conceptos. Esta página es la parte práctica.

Los tres recursos con los que comienzan la mayoría de los registros

Recurso Qué contiene Codificado con
Patient de quién es el registro: nombre, fecha de nacimiento, género, identificadores de otros sistemas sus sistemas de identificadores
Observation cualquier cosa medida o informada: signos vitales, resultados de laboratorio, un peso, una puntuación de síntomas LOINC, unidades UCUM
Condition un diagnóstico o un problema de salud, con su estado a lo largo del tiempo ICD-10 (SNOMED CT detrás de una bandera de licencia)

Los medicamentos (MedicationStatement), las alergias (AllergyIntolerance), las inmunizaciones y los documentos siguen el mismo patrón; los 26 tipos de recursos compatibles se enumeran en la declaración de capacidad en /fhir/R4/metadata.

Antes de empezar

Obtenga una clave de sandbox (sk_test_…) en platform.anpheros.com/dashboard con Get a sandbox key. Nada de lo que cree allí son datos reales de pacientes, y nada es visible para otros proyectos.

export BASE=https://platform.anpheros.com/fhir/R4
export KEY=sk_test_…

Paso 1: Crear un Paciente

curl -X POST "$BASE/Patient" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
  "resourceType": "Patient",
  "identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
  "name": [{"family": "Marin", "given": ["Ioana"]}],
  "gender": "female",
  "birthDate": "1979-04-12"
}'

201 Created, con el id y la versión que el servidor asignó:

{"resourceType": "Patient",
 "identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-10442"}],
 "name": [{"family": "Marin", "given": ["Ioana"]}], "gender": "female", "birthDate": "1979-04-12",
 "id": "d09e3942-ed86-4458-b099-fa674ab21b84",
 "meta": {"versionId": "1", "lastUpdated": "2026-10-12T20:16:51.043Z"}}

Conserve sus propios ids en identifier con un system que usted controle (aquí un número de registro de clínica), para que siempre pueda encontrar al paciente de nuevo con GET $BASE/Patient?identifier=https://clinic.example/mrn|MRN-10442. El id de FHIR es el de la plataforma, y es específico de su proyecto: otro proyecto verá a la misma persona bajo un id diferente.

export PID=d09e3942-ed86-4458-b099-fa674ab21b84

Paso 2: Almacenar una medición como una Observación

La presión arterial es una observación con dos componentes, sistólica y diastólica, cada una con su propio código LOINC. Indique quién la midió: aquí un dispositivo doméstico.

curl -X POST "$BASE/Observation" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
     -H "X-Anpheros-Author-Type: device" -H "Idempotency-Key: bp-2026-10-10-0830" -d '{
  "resourceType": "Observation",
  "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
  "code": {"coding": [{"system": "http://loinc.org", "code": "85354-9", "display": "Blood pressure panel"}]},
  "subject": {"reference": "Patient/'$PID'"},
  "effectiveDateTime": "2026-10-10T08:30:00Z",
  "component": [
    {"code": {"coding": [{"system": "http://loinc.org", "code": "8480-6"}]},
     "valueQuantity": {"value": 138, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}},
    {"code": {"coding": [{"system": "http://loinc.org", "code": "8462-4"}]},
     "valueQuantity": {"value": 88, "unit": "mmHg", "system": "http://unitsofmeasure.org", "code": "mm[Hg]"}}
  ]
}'

La respuesta es el recurso almacenado con id y meta.versionId: "1". Tres detalles son importantes para un registro utilizable:

Los resultados de laboratorio son el mismo recurso con category laboratory y generalmente un referenceRange. Para incorporar informes de laboratorio completos, consulte Cómo importar resultados de laboratorio a un registro FHIR.

Paso 3: registrar un diagnóstico como una Condición

curl -X POST "$BASE/Condition" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
     -H "X-Anpheros-Author-Type: practitioner" -d '{
  "resourceType": "Condition",
  "subject": {"reference": "Patient/'$PID'"},
  "clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active"}]},
  "verificationStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "confirmed"}]},
  "code": {"coding": [{"system": "http://hl7.org/fhir/sid/icd-10", "code": "I10", "display": "Essential (primary) hypertension"}]},
  "onsetDateTime": "2026-03-02"
}'

clinicalStatus (active, resolved, in remission) y verificationStatus (confirmed, provisional) están separados a propósito: un diagnóstico sospechado no es lo mismo que uno confirmado, y un problema resuelto sigue siendo parte del historial.

Paso 4: crear recursos relacionados en una transacción

Cuando un paciente y su primera medición llegan juntos, por ejemplo, desde un sistema de clínica, envíelos como un transaction Bundle. O todo se almacena o nada. Las referencias entre los nuevos recursos utilizan urn:uuid: ids temporales que el servidor reemplaza:

curl -X POST "$BASE" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" -d '{
  "resourceType": "Bundle", "type": "transaction",
  "entry": [
    {"fullUrl": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001",
     "resource": {"resourceType": "Patient", "name": [{"family": "Stan", "given": ["Mihai"]}], "gender": "male", "birthDate": "1990-02-01"},
     "request": {"method": "POST", "url": "Patient"}},
    {"resource": {"resourceType": "Observation", "status": "final",
       "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
       "code": {"coding": [{"system": "http://loinc.org", "code": "29463-7", "display": "Body weight"}]},
       "subject": {"reference": "urn:uuid:9f1c0d1e-0000-4000-8000-000000000001"},
       "effectiveDateTime": "2026-10-10",
       "valueQuantity": {"value": 82.4, "unit": "kg", "system": "http://unitsofmeasure.org", "code": "kg"}},
     "request": {"method": "POST", "url": "Observation"}}
  ]
}'

El transaction-response tiene una entrada por recurso, con "status": "201 Created", su location y el recurso almacenado. El subject de Observation ahora apunta al Patient/fad3665a-… real.

Paso 5: Búsqueda

curl "$BASE/Observation?patient=$PID&code=http://loinc.org|85354-9&date=ge2026-10-01&_sort=-date" \
     -H "Authorization: Bearer $KEY"

Obtendrás un searchset Bundle con total y los recursos coincidentes, los más recientes primero. Otras búsquedas que usarás a menudo son: Condition?patient=$PID&clinical-status=active, Observation?patient=$PID&category=laboratory y Patient/$PID/$everything para el registro completo.

Paso 6: Actualizar sin perder historial

La hipertensión se resuelve. Cambie el estado y agregue la fecha de finalización, y use If-Match con la versión que leyó para que nunca sobrescriba el cambio de otra persona:

curl -X PUT "$BASE/Condition/$CID" -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
     -H 'If-Match: W/"1"' -d '{ …the same Condition…, "clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "resolved"}]}, "abatementDateTime": "2026-10-11" }'

200 OK con ETag: W/"2". Si otra escritura llegó primero, obtendrá 412 y volverá a leer. La versión anterior todavía está allí:

curl "$BASE/Condition/$CID/_history" -H "Authorization: Bearer $KEY"

devuelve ambas versiones: versionId 2 (resolved) y 1 (active). GET $BASE/Condition/$CID/_history/1 lee la antigua. Nada en un registro se sobrescribe silenciosamente.

Paso 7: Ver quién escribió qué

Cada escritura crea un recurso Provenance. Para la lectura de presión arterial:

curl "$BASE/Provenance?target=Observation/$OBS" -H "Authorization: Bearer $KEY"
{"resourceType": "Provenance",
 "target": [{"reference": "Observation/d83d9075-…/_history/1"}],
 "recorded": "2026-10-12T20:16:51.056000Z",
 "activity": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation", "code": "CREATE"}]},
 "agent": [{"type": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "author"}]},
            "who": {"identifier": {"system": "https://anpheros.com/fhir/CodeSystem/author-type", "value": "device"}, "display": "proj_…"},
            "onBehalfOf": {"identifier": {"system": "https://anpheros.com/fhir/sid/organization", "value": "org_…"}, "display": "…"}}]}

El tipo de autor que envió (device) se registra con el proyecto y la organización. Envíe X-Anpheros-Author-Ref: Practitioner/<id> para nombrar al clínico detrás de una escritura.

Paso 8: el registro como resumen

curl "$BASE/Patient/$PID/\$summary" -H "Authorization: Bearer $KEY"

devuelve un Resumen Internacional de Paciente (International Patient Summary): un document Bundle que comienza con un Composition y tiene secciones como Problemas, Medicamentos, Alergias y Signos Vitales, construido a partir de los recursos anteriores. Ese es el formato para entregar a otro sistema o imprimir para un médico (plataforma FHIR).

¿Prefiere JSON sin FHIR?

Los mismos datos están disponibles a través de una vista REST más simple, /v1, con los mismos ids: POST /v1/patients/{id}/observations toma {"code": "85354-9", "category": "vital-signs", "effective_at": "…", "components": […]} y almacena la misma FHIR Observation. Utilice la que mejor se adapte a su código. Consulte la API de datos médicos y los SDK.

Preguntas frecuentes

¿Cuál es la mejor manera de almacenar historiales médicos?

Como recursos codificados y versionados con un registro de quién escribió cada uno. HL7 FHIR R4 le proporciona la estructura (Patient, Observation, Condition y otros), sistemas de codificación estándar como LOINC e ICD-10, e historial; un backend FHIR añade búsqueda, consentimiento y procedencia.

¿Necesito un servidor FHIR para usar FHIR?

Necesita un lugar que almacene y busque recursos FHIR y que haga cumplir quién puede leerlos. Puede ejecutar su propio servidor FHIR de código abierto o utilizar uno gestionado como Anpheros; Cómo Anpheros se compara con otros servidores FHIR sopesa las opciones, y FHIR vs. una base de datos médica personalizada cubre la creación de su propio esquema en su lugar.

¿Cómo almaceno la presión arterial en FHIR?

Como una Observation con el código LOINC 85354-9 y dos entradas component: sistólica 8480-6 y diastólica 8462-4, cada una con un valueQuantity en mm[Hg].

¿Puedo cambiar un recurso almacenado?

Sí, con PUT y If-Match. Cada cambio crea una nueva versión; las versiones anteriores permanecen legibles a través de _history, y Provenance registra quién hizo cada cambio. Las eliminaciones son lógicas y conservan el historial.

Relacionado

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy