# Cómo almacenar registros médicos usando FHIR R4

> Tutorial: cree un Paciente, una Observación de presión arterial y una Condición, use una transacción, busque, actualice con historial y lea la procedencia — cada solicitud con curl y la respuesta real, en el sandbox gratuito.

Source: https://developers.anpheros.com/es/guides/store-medical-records-fhir

**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](https://developers.anpheros.com/es/guides/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](https://developers.anpheros.com/es/guides/fhir) 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](https://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.

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

## Paso 1: Crear un Paciente

```bash
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ó:

```json
{"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.

```bash
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.

```bash
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:

- **Códigos, no etiquetas.** `85354-9` significa "panel de presión arterial" en todos los sistemas FHIR; un texto libre "BP" no lo hace. Busque códigos con `GET /v1/terminology/loinc?q=blood pressure` ([Sistemas de códigos FHIR](https://developers.anpheros.com/es/guides/fhir-code-systems)).
- **Unidades UCUM** (`mm[Hg]`, `kg`, `mg/dL`) en `valueQuantity.code`, para que los valores puedan compararse y convertirse.
- **`Idempotency-Key`.** Un reintento después de un tiempo de espera devuelve la primera respuesta en lugar de almacenar la lectura dos veces.

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](https://developers.anpheros.com/es/guides/import-lab-results-fhir).

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

```bash
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:

```bash
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

```bash
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:

```bash
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í:

```bash
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:

```bash
curl "$BASE/Provenance?target=Observation/$OBS" -H "Authorization: Bearer $KEY"
```

```json
{"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

```bash
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](https://developers.anpheros.com/es/guides/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](https://developers.anpheros.com/es/guides/medical-data-api) y los [SDK](https://developers.anpheros.com/es/guides/sdks).

## 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](https://developers.anpheros.com/es/guides/fhir-server-comparison) sopesa las opciones, y [FHIR vs. una base de datos médica personalizada](https://developers.anpheros.com/es/guides/fhir-vs-custom-database) 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

- [Plataforma FHIR](https://developers.anpheros.com/es/guides/fhir): los conceptos, tipos de recursos y operaciones
- [Sistemas de códigos FHIR](https://developers.anpheros.com/es/guides/fhir-code-systems): LOINC, ICD-10, ATC, UCUM
- [Cómo importar resultados de laboratorio a un registro FHIR](https://developers.anpheros.com/es/guides/import-lab-results-fhir)
- [API de datos médicos](https://developers.anpheros.com/es/guides/medical-data-api): la vista REST más sencilla de los mismos datos
- [Base de datos FHIR y sandbox gratuitos](https://developers.anpheros.com/es/guides/free-fhir-database)
