# Primeros pasos

> Desde una clave de API hasta leer y escribir el registro FHIR R4 de un paciente en el sandbox: claves, primeras llamadas, escrituras con procedencia, documentos, contexto de IA, IPS, consentimiento, webhooks e informes de laboratorio.

Source: https://developers.anpheros.com/es/guides/getting-started

Anpheros Platform es un backend de datos de salud: un registro FHIR R4 por paciente, aislamiento de proyectos,
procedencia en cada escritura y una API REST simple sobre los mismos datos. Esta guía te lleva
desde cero hasta leer y escribir el registro de un paciente en el sandbox.

URL base (el sandbox y la producción la comparten; la clave decide el plano de datos):

```
https://platform.anpheros.com
```

Referencia interactiva: `/docs` (OpenAPI) y `/fhir/R4/metadata` (CapabilityStatement).

## 1. Obtener una clave (1 minuto)

El sandbox es de autoservicio. Inicie sesión en el panel (`https://platform.anpheros.com/dashboard/`) con Google y presione **Obtener una clave de sandbox**: obtendrá una organización, un proyecto de sandbox con sus propios pacientes sintéticos y una clave, que se muestra una vez. Lo mismo a través de la API de administración, con su token de usuario de Firebase:

```bash
curl -X POST $BASE/admin/sandbox/quickstart -H "Authorization: Bearer $FIREBASE_ID_TOKEN"
# {"organization": {…}, "project": {"id": "proj_…", "environment": "sandbox", …}, "key": {"key": "sk_test_…", …}, "sandbox": {…}}
```

O paso a paso:

```bash
# 1. an organization (you become its owner)
curl -X POST $BASE/admin/organizations -H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
     -H 'content-type: application/json' -d '{"name":"CardioAI SRL","kind":"developer","country":"RO"}'
# 2. a sandbox project (it comes with its own synthetic patients)
curl -X POST $BASE/admin/organizations/org_…/projects -H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
     -H 'content-type: application/json' -d '{"name":"CardioAI dev","environment":"sandbox"}'
# 3. a key — the plain key is returned exactly once
curl -X POST $BASE/admin/projects/proj_…/keys -H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
     -H 'content-type: application/json' -d '{"name":"local dev","scopes":["read","write"]}'
```

Obtendrá `sk_test_…`. Las claves de sandbox solo ven datos de sandbox. Las claves de producción (`sk_live_…`) se emiten a organizaciones verificadas con un DPA firmado; escriba a platform@anpheros.com. El sandbox es gratuito; la producción comienza en 99 € al mes y el primer mes es gratuito (consulte [Precios](https://developers.anpheros.com/es/guides/pricing)).

## 2. Primera llamada (1 minuto)

Tu proyecto sandbox ya tiene su propia copia de 30 pacientes sintéticos, con seis meses de historial
hasta el día en que se creó el proyecto: adultos, niños y personas mayores de toda la UE, con
condiciones (ICD-10), medicamentos (ATC), alergias, resultados de laboratorio y signos vitales (LOINC). La copia
pertenece a tu proyecto: cambia o elimina cualquier cosa; ningún otro proyecto la verá. **Restablecer pacientes de prueba** en el panel de control (o `POST /admin/projects/{id}/sandbox/reset`) los devuelve a su estado original, con nuevos ids; los pacientes que creaste tú mismo no se verán afectados. Cada paciente sintético mantiene un identificador estable a través de los restablecimientos: `Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02`
siempre es Elena Ionescu.

```bash
export KEY=sk_test_…
curl $BASE/v1/patients -H "Authorization: Bearer $KEY"
```

```json
{"data":[{"id":"…","given":"Elena","family":"Ionescu","birth_date":"1985-09-03","gender":"female",…,"fhir":"Patient/…"}, …],"total":30,"next_cursor":null}
```

Los límites del sandbox son generosos pero finitos: 10 000 escrituras de recursos al día por proyecto, 50 pacientes propios además de los sintéticos, 250 MB de documentos (ver [límites](https://developers.anpheros.com/es/guides/limits)).

## 3. Leer un registro

```bash
# lab results, newest first
curl "$BASE/v1/patients/$PID/observations?category=laboratory&limit=10" -H "Authorization: Bearer $KEY"
# active medications
curl "$BASE/v1/patients/$PID/medications?status=active" -H "Authorization: Bearer $KEY"
# everything on one timeline
curl "$BASE/v1/patients/$PID/timeline?from=2026-06-01" -H "Authorization: Bearer $KEY"
# the same data, strict FHIR
curl "$BASE/fhir/R4/Observation?patient=$PID&code=http://loinc.org|4548-4&_sort=-date" -H "Authorization: Bearer $KEY"
```

Los IDs son idénticos en `/v1` y `/fhir/R4`; cada objeto v1 lleva su referencia `fhir`.
`_summary=count` devuelve solo el total; `_elements=code,effectiveDateTime` devuelve recursos "slim" etiquetados `SUBSETTED`.

## 4. Escribir

Indique quién es el autor. `author_type` es `patient`, `practitioner`, `device`, `import` o `ai`;
si lo omite, la plataforma registra `import`, nunca `patient` por defecto.
Las escrituras con `author_type` `ai` siguen la [HL7 AI Transparency on FHIR](https://build.fhir.org/ig/HL7/aitransparency-ig/):
el recurso lleva la etiqueta de seguridad `AIAST` (*Artificial Intelligence asserted*) y su Provenance tiene la razón
`AIAST`, el rol del agente `Artificial-Intelligence` y el perfil `AI-Provenance`. Para nombrar el modelo, regístrelo como un
`Device` (tipo `Artificial-Intelligence`, nombre, versión, fabricante) y envíe `X-Anpheros-Author-Ref: Device/<id>`.

```bash
curl -X POST "$BASE/v1/patients/$PID/observations" -H "Authorization: Bearer $KEY" \
     -H 'content-type: application/json' -H "Idempotency-Key: $(uuidgen)" -d '{
  "code": "2339-0", "display": "Glucose", "category": "laboratory",
  "value": 112, "unit": "mg/dL", "effective_at": "2026-09-19T08:10:00Z",
  "author_type": "device"
}'
```

La respuesta es la observación almacenada con `id`, `fhir` y `updated_at`. Repetir la misma
solicitud exacta con el mismo `Idempotency-Key` devuelve la misma respuesta y no crea nada.

## 5. Documentos

```bash
# 1. create the document → upload target
curl -X POST "$BASE/v1/patients/$PID/documents" -H "Authorization: Bearer $KEY" -H 'content-type: application/json' \
     -d '{"title":"Analize 2026-09-14","kind":"lab_report","content_type":"application/pdf","date":"2026-09-14"}'
# 2. upload the bytes to the returned url (direct to storage, or through the platform)
curl -X PUT "$BASE/v1/documents/$DOC/content" -H "Authorization: Bearer $KEY" -H 'content-type: application/pdf' --data-binary @analize.pdf
```

El original nunca se modifica después de eso; se registran `sha256` y `size`, y cualquier valor que
extraiga posteriormente apunta de nuevo al documento a través de `derived_from`.

## 6. Procedencia

```bash
curl "$BASE/v1/patients/$PID/provenance/Observation/$OBS" -H "Authorization: Bearer $KEY"
```

Una entrada por versión: quién (tipo de autor y proyecto), cuándo, desde qué sistema de origen.

## Reglas que conviene conocer

- **Aislamiento**: un proyecto ve los pacientes que creó (más los pacientes compartidos del sandbox). Los pacientes de cualquier otra persona no existen para ti: `404`, nunca `403`.
- **IDs por pares**: el ID de paciente que ves es tuyo. Otro proyecto ve a la misma persona bajo un ID diferente. Almacena nuestros IDs libremente; nunca intentes correlacionarlos.
- **Procedencia**: cada escritura deja un recurso Provenance. Nada se sobrescribe silenciosamente; el historial está disponible en `/fhir/R4/{Type}/{id}/_history`.
- **Errores**: los endpoints FHIR devuelven `OperationOutcome`; `/v1` y `/admin` devuelven `{"error": {"type", "message", "field"}}`. Cada respuesta lleva `Anpheros-Request-Id`; cita esto cuando nos escribas.
- **Límites**: 600 solicitudes/minuto por clave por defecto, 200 elementos por página, 25 MB por documento.

## 7. Contexto para un modelo de IA

En lugar de extraer registros brutos y decidir qué se ajusta a una indicación, solicite a la plataforma un contexto:

```bash
curl -X POST "$BASE/v1/context" -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{
  "patient": "'$PID'",
  "task": "medication review before a cardiology visit",
  "question": "How did blood pressure evolve over the last 3 months?",
  "budget_tokens": 1500,
  "format": "text"
}'
```

Obtendrá secciones (tarjeta de resumen, condiciones, medicamentos, alergias, laboratorios, signos vitales con tendencias semanales y marcadores antes/después del tratamiento, síntomas, línea de tiempo, documentos), cada elemento etiquetado con `author_type` y `source`, una lista de lo que se omitió para ajustarse al presupuesto, advertencias y un `manifest_id` que vincula la llamada al registro de auditoría. Los valores producidos por la IA nunca se mezclan con los hechos: aparecen solo bajo `ai_notes`. También se aceptan necesidades explícitas:
`"needs": ["labs:4548-4", "vitals:trend:85354-9", "timeline:180d"]`.

## 8. Estándares

- `GET /fhir/R4/Patient/{id}/$summary` devuelve un Bundle de documento International Patient Summary.
- `POST /fhir/R4/Observation/$validate?profile=eu-lab` informa cómo un resultado de laboratorio se compara con el perfil de resultado del Informe de Laboratorio 2.1.0 de HL7 Europe (errores, advertencias, información): categoría, código (LOINC preferido), sujeto, tiempo efectivo, un intérprete y un valor a menos que el resultado solo se registre o se cancele.
- `GET /v1/terminology/loinc?q=hba1c` busca el subconjunto de LOINC empaquetado y `GET /v1/search?q=metformin` el catálogo de síntomas, afecciones y medicamentos; las observaciones creadas sin un nombre para mostrar obtienen automáticamente el nombre LOINC.

## 9. Consentimiento del paciente (OAuth 2.1 + SMART on FHIR)

Las claves de API ven los pacientes que creó su proyecto. Para acceder al registro existente de una persona, pídales:

1. Registre una aplicación: `POST /admin/projects/{id}/applications` con su URI de redirección
   (`public` para aplicaciones móviles/web con PKCE, `confidential` para servidores; el secreto se muestra una vez).
2. Envíe a la persona a la página de consentimiento:
   `GET /oauth/authorize?response_type=code&client_id=…&redirect_uri=…&state=…&code_challenge=…&code_challenge_method=S256&scope=patient/Observation.rs?category=laboratory patient/MedicationStatement.r offline_access&purpose=treatment&lang=ro`
   Inician sesión en Anpheros, ven lo que solicita en lenguaje claro, eligen el registro (el suyo,
   el de un dependiente o el que su aplicación creó para ellos) y cuánto dura el acceso.
3. Intercambie el código: `POST /oauth/token` (`authorization_code` + `code_verifier`). Recibe un
   token de acceso (30 min), un token de actualización (30 días, rotado al usarse) y el ID del paciente.
4. Llame a la API con `Authorization: Bearer at_…`. Solo ve a ese paciente, solo los tipos de recursos
   y acciones en los ámbitos; las lecturas fuera de ámbito responden `403`, las búsquedas se filtran.

La persona puede revocar en cualquier momento desde Anpheros; la siguiente llamada responde `401`. Cada concesión se
refleja como un recurso FHIR `Consent`, y cada acceso bajo él se registra y es visible para la
persona. Descubrimiento: `/.well-known/smart-configuration`.

## 10. Webhooks

Deja que la plataforma te llame en lugar de hacer polling:

```bash
curl -X POST $BASE/v1/webhooks -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://your.app/anpheros/hook", "events": ["*"]}'
```

Conserva el `secret` de la respuesta y verifica `Anpheros-Signature` en cada entrega
(`verifyWebhookSignature` en ambos SDKs). Los eventos transportan IDs y versiones, no datos clínicos.
Detalles, reintentos y ejemplos: [webhooks.md](https://developers.anpheros.com/es/guides/webhooks).

## 11. Organizaciones y profesionales

Las clínicas, los laboratorios y las personas que trabajan en ellos son recursos de primera clase: `Organization`, `Practitioner`, `PractitionerRole`. Son recursos de **directorio**: no de pacientes, legibles por cada proyecto en el mismo entorno, modificables solo por el proyecto que los creó.

```bash
curl -X POST $BASE/fhir/R4/Practitioner -H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json" \
  -d '{"resourceType":"Practitioner","active":true,"name":[{"family":"Popescu","given":["Ana"],"prefix":["Dr."]}]}'
```

Nombra al profesional detrás de una escritura con `X-Anpheros-Author-Ref: Practitioner/<id>` (o un `PractitionerRole`, `Organization`, `Device`): el Provenance generado por el servidor contendrá entonces `agent.who.reference`, y `GET /fhir/R4/Provenance?agent=Practitioner/<id>` listará todo lo que esa persona registró. Búsqueda: `Organization?name=`, `?identifier=`, `?type=`, `Practitioner?name=`, `?family=`, `?given=`, `PractitionerRole?practitioner=`, `?organization=`, `?role=`, `?specialty=`, `?active=`.

¿Quién está trabajando detrás de tu aplicación? Envía `X-Anpheros-Acting-As: PractitionerRole/<id>` (o `Practitioner/<id>`) en cualquier solicitud `/v1` o `/fhir/R4` realizada con una clave de proyecto. La persona debe existir en el directorio y estar activa. La referencia se escribe en el registro de acceso, se convierte en el autor de las escrituras de esa solicitud (a menos que establezcas `X-Anpheros-Author-Ref`) y se muestra al paciente por nombre en sus conexiones ("Dr. Ana Popescu · Clinica Dente leyó tus resultados de laboratorio").

## 12. Informes de laboratorio en una sola llamada

Envía un informe de laboratorio completo (CSV, HL7 v2 ORU^R01 o JSON) y obtén Observaciones de laboratorio con LOINC
y rangos de referencia; reenviar es seguro. Detalles: [lab-connector.md](https://developers.anpheros.com/es/guides/lab-connector).

```bash
curl -X POST "$BASE/v1/patients/$PATIENT/labs/import" -H "Authorization: Bearer $KEY" -H "Content-Type: text/csv" --data-binary @report.csv
```

## Retroalimentación de conformidad en escrituras

Cada `POST`/`PUT` de un recurso clínico se verifica contra el perfil IPS de su sección y, para
observaciones de laboratorio, las reglas de informe de laboratorio de HL7 Europe. La escritura nunca se rechaza por
motivos de perfil (los errores estructurales de FHIR aún lo son); cuando falta algo, la respuesta lleva

```
Anpheros-Conformance: warnings=2; IPS Condition: Condition without code | ...
```

Corrija lo que nombra y el recurso se incluirá en el `$summary` del paciente. Tipos de recursos añadidos
el 22 de septiembre de 2026: `Immunization`, `MedicationAdministration` (búsqueda `statement=MedicationStatement/{id}`),
`RelatedPerson`, `QuestionnaireResponse`, `Basic`. Las escrituras realizadas por otros proyectos en un registro que puede
ver llegan como eventos de webhook con `data.external = true` — consulte [`docs/webhooks.md`](https://developers.anpheros.com/es/guides/webhooks).
