# Introducere

> De la o cheie API la citirea și scrierea înregistrării FHIR R4 a unui pacient în sandbox: chei, primele apeluri, scrieri cu proveniență, documente, context AI, IPS, consimțământ, webhooks și rapoarte de laborator.

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

Platforma Anpheros este un backend de date medicale: o înregistrare FHIR R4 per pacient, izolare de proiect,
proveniență la fiecare scriere și o API REST simplă deasupra acelorași date. Acest ghid te va
conduce de la zero la citirea și scrierea înregistrării unui pacient în sandbox.

URL de bază (sandbox și producție îl partajează; cheia decide planul de date):

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

Referință interactivă: `/docs` (OpenAPI) și `/fhir/R4/metadata` (CapabilityStatement).

## 1. Obține o cheie (1 minut)

Sandbox-ul este self-service. Autentifică-te în dashboard (`https://platform.anpheros.com/dashboard/`)
cu Google și apasă **Get a sandbox key**: vei primi o organizație, un proiect sandbox cu proprii
pacienți sintetici și o cheie — afișată o singură dată. Același lucru prin Admin API, cu token-ul tău de utilizator 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": {…}}
```

Sau pas cu pas:

```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"]}'
```

Vei primi `sk_test_…`. Cheile sandbox accesează întotdeauna doar date sandbox. Cheile de producție (`sk_live_…`) sunt
emise organizațiilor verificate cu un DPA semnat — scrie la platform@anpheros.com. Sandbox-ul este gratuit;
producția începe de la 99 € pe lună, iar prima lună este gratuită (vezi [Pricing](https://developers.anpheros.com/ro/guides/pricing)).

## 2. Primul apel (1 minut)

Proiectul dumneavoastră sandbox are deja propria copie a 30 de pacienți sintetici, cu șase luni de istoric
până în ziua creării proiectului: adulți, copii și persoane în vârstă din întreaga UE, cu
afecțiuni (ICD-10), medicamente (ATC), alergii, rezultate de laborator și semne vitale (LOINC). Copia
aparține proiectului dumneavoastră: modificați sau ștergeți orice — niciun alt proiect nu o vede. **Resetați pacienții de test** în tabloul de bord (sau `POST /admin/projects/{id}/sandbox/reset`) îi readuce așa cum erau, cu noi ID-uri; pacienții creați de dumneavoastră nu sunt afectați. Fiecare pacient sintetic păstrează un identificator stabil pe parcursul resetărilor: `Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02`
este întotdeauna 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}
```

Limitele sandbox-ului sunt generoase, dar finite: 10 000 de scrieri de resurse pe zi per proiect, 50 de pacienți proprii pe lângă cei sintetici, 250 MB de documente (vezi [limite](https://developers.anpheros.com/ro/guides/limits)).

## 3. Citirea unui înregistrări

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

ID-urile sunt identice în `/v1` și `/fhir/R4`; fiecare obiect v1 poartă referința sa `fhir`.
`_summary=count` returnează doar totalul; `_elements=code,effectiveDateTime` returnează resurse slim etichetate `SUBSETTED`.

## 4. Scriere

Spune cine este autorul. `author_type` este `patient`, `practitioner`, `device`, `import` sau `ai`;
dacă îl omiteți, platforma înregistrează `import`, niciodată `patient` prin presupunere.
Scrierile cu `author_type` `ai` respectă [HL7 AI Transparency on FHIR](https://build.fhir.org/ig/HL7/aitransparency-ig/):
resursa poartă eticheta de securitate `AIAST` (*Artificial Intelligence asserted*) iar Provenance-ul său are motivul
`AIAST`, rolul agentului `Artificial-Intelligence` și profilul `AI-Provenance`. Pentru a numi modelul, înregistrați-l ca
`Device` (tip `Artificial-Intelligence`, nume, versiune, producător) și trimiteți `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"
}'
```

Răspunsul este observația stocată cu `id`, `fhir` și `updated_at`. Repetarea exactă
a aceleiași cereri cu același `Idempotency-Key` returnează același răspuns și nu creează nimic.

## 5. Documente

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

Originalul nu este niciodată modificat ulterior; `sha256` și `size` sunt înregistrate, iar orice valori pe care le extrageți ulterior indică înapoi la document prin `derived_from`.

## 6. Proveniență

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

O intrare per versiune: cine (tip autor și proiect), când, din ce sistem sursă.

## Reguli de reținut

- **Izolare**: un proiect vede pacienții pe care i-a creat (plus pacienții partajați din sandbox). Pacienții altcuiva nu există pentru tine: `404`, niciodată `403`.
- **ID-uri pereche**: ID-ul pacientului pe care îl vezi este al tău. Un alt proiect vede aceeași persoană sub un ID diferit. Stocați ID-urile noastre liber; nu încercați niciodată să le corelați.
- **Proveniență**: fiecare scriere lasă o resursă Provenance. Nimic nu este suprascris silențios; istoricul este disponibil la `/fhir/R4/{Type}/{id}/_history`.
- **Erori**: endpoint-urile FHIR returnează `OperationOutcome`; `/v1` și `/admin` returnează `{"error": {"type", "message", "field"}}`. Fiecare răspuns poartă `Anpheros-Request-Id`; citați-l când ne scrieți.
- **Limite**: 600 de cereri/minut per cheie în mod implicit, 200 de elemente per pagină, 25 MB per document.

## 7. Context pentru un model AI

În loc să extrageți înregistrări brute și să decideți ce se potrivește unui prompt, solicitați platformei un context:

```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"
}'
```

Veți primi secțiuni (card rezumat, afecțiuni, medicamente, alergii, analize, semne vitale cu tendințe săptămânale și markeri înainte/după tratament, simptome, cronologie, documente), fiecare element etichetat cu `author_type` și `source`, o listă a ceea ce a fost omis pentru a se încadra în buget, avertismente și un `manifest_id` care leagă apelul de logul de audit. Valorile produse de AI nu sunt niciodată amestecate cu fapte: apar doar sub `ai_notes`. Sunt acceptate și nevoi explicite:
`"needs": ["labs:4548-4", "vitals:trend:85354-9", "timeline:180d"]`.

## 8. Standarde

- `GET /fhir/R4/Patient/{id}/$summary` returnează un document International Patient Summary Bundle.
- `POST /fhir/R4/Observation/$validate?profile=eu-lab` raportează cum se compară un rezultat de laborator cu profilul de rezultat HL7 Europe Laboratory Report 2.1.0 (erori, avertismente, informații): categorie, cod (LOINC preferat), subiect, timp efectiv, un executant și o valoare, cu excepția cazului în care rezultatul este doar înregistrat sau anulat.
- `GET /v1/terminology/loinc?q=hba1c` caută subsetul LOINC din bundle și `GET /v1/search?q=metformin` catalogul de simptome, afecțiuni și medicamente; observațiile create fără un nume de afișare primesc automat numele LOINC.

## 9. Consimțământul pacientului (OAuth 2.1 + SMART on FHIR)

Cheile API văd pacienții creați de proiectul dumneavoastră. Pentru a accesa înregistrarea existentă a unei persoane, întrebați-o:

1. Înregistrați o aplicație: `POST /admin/projects/{id}/applications` cu URI-ul dumneavoastră de redirecționare
   (`public` pentru aplicații mobile/web cu PKCE, `confidential` pentru servere; secretul este afișat o singură dată).
2. Trimiteți persoana la pagina de consimțământ:
   `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`
   Aceasta se autentifică în Anpheros, vede ce solicitați în limbaj clar, alege înregistrarea (propria sa,
   a unui dependent sau cea creată de aplicația dumneavoastră pentru ea) și cât timp durează accesul.
3. Schimbați codul: `POST /oauth/token` (`authorization_code` + `code_verifier`). Veți primi un
   token de acces (30 min), un token de reîmprospătare (30 de zile, rotit la utilizare) și ID-ul pacientului.
4. Apelați API-ul cu `Authorization: Bearer at_…`. Veți vedea doar acel pacient, doar tipurile de resurse
   și acțiunile din scope-uri; citirile în afara scope-ului răspund cu `403`, căutările sunt filtrate.

Persoana poate revoca consimțământul în orice moment din Anpheros; următorul apel va răspunde cu `401`. Fiecare acord este
reflectat ca o resursă FHIR `Consent`, iar fiecare acces sub acesta este înregistrat și vizibil pentru
persoană. Descoperire: `/.well-known/smart-configuration`.

## 10. Webhooks

Lăsați platforma să vă apeleze pe dvs. în loc să interogați:

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

Păstrați `secret` din răspuns și verificați `Anpheros-Signature` la fiecare livrare
(`verifyWebhookSignature` în ambele SDK-uri). Evenimentele transportă ID-uri și versiuni, nu date clinice.
Detalii, reîncercări și exemple: [webhooks.md](https://developers.anpheros.com/ro/guides/webhooks).

## 11. Organizații și practicieni

Clinicile, laboratoarele și persoanele care lucrează acolo sunt resurse de prim rang: `Organization`, `Practitioner`, `PractitionerRole`. Acestea sunt resurse de **director**: nicio pacientă, citibilă de fiecare proiect din același mediu, modificabilă doar de proiectul care le-a creat.

```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."]}]}'
```

Denumiți practicienul din spatele unei scrieri cu `X-Anpheros-Author-Ref: Practitioner/<id>` (sau un `PractitionerRole`, `Organization`, `Device`): Provenance generat de server va conține apoi `agent.who.reference`, iar `GET /fhir/R4/Provenance?agent=Practitioner/<id>` listează tot ce a înregistrat acea persoană. Căutare: `Organization?name=`, `?identifier=`, `?type=`, `Practitioner?name=`, `?family=`, `?given=`, `PractitionerRole?practitioner=`, `?organization=`, `?role=`, `?specialty=`, `?active=`.

Cine lucrează în spatele aplicației dumneavoastră? Trimiteți `X-Anpheros-Acting-As: PractitionerRole/<id>` (sau `Practitioner/<id>`) la orice cerere `/v1` sau `/fhir/R4` făcută cu o cheie de proiect. Persoana trebuie să existe în director și să fie activă. Referința este scrisă în jurnalul de acces, devine autorul scrierilor acelei cereri (cu excepția cazului în care setați `X-Anpheros-Author-Ref`) și este afișată pacientului pe nume în conexiunile acestuia ("Dr. Ana Popescu · Clinica Dente a citit rezultatele dumneavoastră de laborator").

## 12. Rapoarte de laborator într-un singur apel

Trimiteți un raport de laborator complet (CSV, HL7 v2 ORU^R01 sau JSON) și primiți Observații de laborator cu LOINC
și intervale de referință; re-trimiterea este sigură. Detalii: [lab-connector.md](https://developers.anpheros.com/ro/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
```

## Feedback de conformitate la scrieri

Fiecare `POST`/`PUT` dintr-o resursă clinică este verificat în raport cu profilul IPS al secțiunii sale și, pentru
observațiile de laborator, cu regulile HL7 Europe pentru rapoarte de laborator. Scrierea nu este niciodată respinsă din
motive de profil (erorile structurale FHIR sunt în continuare respinse); atunci când lipsește ceva, răspunsul conține

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

Corectați ceea ce numește și resursa va fi inclusă în `$summary` pacientului. Tipuri de resurse adăugate
pe 22 septembrie 2026: `Immunization`, `MedicationAdministration` (căutare `statement=MedicationStatement/{id}`),
`RelatedPerson`, `QuestionnaireResponse`, `Basic`. Scrierile efectuate de alte proiecte într-un registru pe care îl puteți
vedea ajung ca evenimente webhook cu `data.external = true` — consultați [`docs/webhooks.md`](https://developers.anpheros.com/ro/guides/webhooks).
