# Rozpoczęcie pracy

> Od klucza API po odczyt i zapis rekordu FHIR R4 pacjenta w piaskownicy: klucze, pierwsze wywołania, zapisy z proweniencją, dokumenty, kontekst AI, IPS, zgody, webhooks i raporty laboratoryjne.

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

Platforma Anpheros to backend danych medycznych: rekord FHIR R4 na pacjenta, izolacja projektów,
proweniencja przy każdym zapisie i proste API REST na bazie tych samych danych. Ten przewodnik przeprowadzi Cię
od zera do odczytu i zapisu rekordu pacjenta w piaskownicy.

Adres bazowy URL (piaskownica i produkcja dzielą ten sam adres; klucz decyduje o płaszczyźnie danych):

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

Interaktywny odnośnik: `/docs` (OpenAPI) i `/fhir/R4/metadata` (CapabilityStatement).

## 1. Uzyskaj klucz (1 minuta)

Środowisko sandbox jest samoobsługowe. Zaloguj się do panelu (`https://platform.anpheros.com/dashboard/`)
za pomocą Google i naciśnij **Uzyskaj klucz sandbox**: otrzymasz organizację, projekt sandbox z własnymi
syntetycznymi pacjentami i klucz — wyświetlany raz. To samo przez Admin API, z Twoim tokenem użytkownika 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": {…}}
```

Lub krok po kroku:

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

Otrzymasz `sk_test_…`. Klucze sandbox zawsze widzą tylko dane sandbox. Klucze produkcyjne (`sk_live_…`) są
wydawane zweryfikowanym organizacjom z podpisaną umową DPA — napisz na adres platform@anpheros.com. Środowisko sandbox jest bezpłatne;
produkcja zaczyna się od 99 EUR miesięcznie, a pierwszy miesiąc jest bezpłatny (patrz [Cennik](https://developers.anpheros.com/pl/guides/pricing)).

## 2. Pierwsze wywołanie (1 minuta)

Twój projekt sandbox ma już własną kopię 30 syntetycznych pacjentów z sześciomiesięczną historią
do dnia utworzenia projektu: dorośli, dzieci i osoby starsze z całej UE, z
chorobami (ICD-10), lekami (ATC), alergiami, wynikami badań laboratoryjnych i danymi życiowymi (LOINC). Kopia
należy do Twojego projektu: zmieniaj lub usuwaj wszystko – żaden inny projekt tego nie widzi. **Resetuj pacjentów testowych** w panelu (lub `POST /admin/projects/{id}/sandbox/reset`) przywraca ich do stanu
początkowego z nowymi identyfikatorami; pacjenci utworzeni przez Ciebie nie są naruszani. Każdy syntetyczny pacjent zachowuje stabilny identyfikator po resetach: `Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02`
zawsze jest Eleną 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}
```

Limity sandbox są hojne, ale skończone: 10 000 zapisów zasobów dziennie na projekt, 50 własnych pacjentów oprócz syntetycznych, 250 MB dokumentów (patrz [limity](https://developers.anpheros.com/pl/guides/limits)).

## 3. Odczyt rekordu

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

Identyfikatory są identyczne w `/v1` i `/fhir/R4`; każdy obiekt v1 zawiera odniesienie `fhir`.
`_summary=count` zwraca tylko sumę; `_elements=code,effectiveDateTime` zwraca zasoby typu slim oznaczone jako `SUBSETTED`.

## 4. Pisanie

Podaj autora. `author_type` to `patient`, `practitioner`, `device`, `import` lub `ai`;
jeśli go pominiesz, platforma zapisze `import`, nigdy domyślnie `patient`.
Pisanie z `author_type` `ai` jest zgodne z [HL7 AI Transparency on FHIR](https://build.fhir.org/ig/HL7/aitransparency-ig/):
zasób zawiera etykietę bezpieczeństwa `AIAST` (*Artificial Intelligence asserted*) i jego Provenance ma powód
`AIAST`, rolę agenta `Artificial-Intelligence` i profil `AI-Provenance`. Aby nazwać model, zarejestruj go jako
`Device` (typ `Artificial-Intelligence`, nazwa, wersja, producent) i wyślij `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"
}'
```

Odpowiedzią jest zapisana obserwacja z `id`, `fhir` i `updated_at`. Powtórzenie dokładnie
tego samego żądania z tym samym `Idempotency-Key` zwraca tę samą odpowiedź i niczego nie tworzy.

## 5. Dokumenty

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

Oryginał nigdy nie jest modyfikowany po tym; `sha256` i `size` są rejestrowane, a wszelkie wartości, które
później wyodrębnisz, wskazują z powrotem na dokument za pomocą `derived_from`.

## 6. Provenance

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

Jeden wpis na wersję: kto (typ autora i projekt), kiedy, z jakiego systemu źródłowego.

## Zasady, o których warto wiedzieć

- **Izolacja**: projekt widzi pacjentów, których utworzył (oraz udostępnionych pacjentów z piaskownicy). Pacjenci innych użytkowników nie istnieją dla Ciebie: `404`, nigdy `403`.
- **Identyfikatory parami**: identyfikator pacjenta, który widzisz, jest Twój. Inny projekt widzi tę samą osobę pod innym identyfikatorem. Przechowuj nasze identyfikatory swobodnie; nigdy nie próbuj ich korelować.
- **Pochodzenie**: każda operacja zapisu pozostawia zasób Provenance. Nic nie jest nadpisywane bez śladu; historia jest dostępna pod adresem `/fhir/R4/{Type}/{id}/_history`.
- **Błędy**: punkty końcowe FHIR zwracają `OperationOutcome`; `/v1` i `/admin` zwracają `{"error": {"type", "message", "field"}}`. Każda odpowiedź zawiera `Anpheros-Request-Id`; zacytuj ją, gdy się z nami kontaktujesz.
- **Limity**: domyślnie 600 żądań/minutę na klucz, 200 elementów na stronę, 25 MB na dokument.

## 7. Kontekst dla modelu AI

Zamiast pobierać surowe rekordy i decydować, co pasuje do zapytania, poproś platformę o kontekst:

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

Otrzymujesz sekcje (karta podsumowania, schorzenia, leki, alergie, wyniki badań laboratoryjnych, parametry życiowe z tygodniowymi trendami i znacznikami przed/po leczeniu, objawy, oś czasu, dokumenty), każdy element opatrzony etykietą `author_type` i `source`, listą tego, co zostało pominięte, aby zmieścić się w budżecie, ostrzeżeniami i `manifest_id`, które powiązuje wywołanie z dziennikiem audytu. Wartości generowane przez AI nigdy nie są mieszane z faktami: pojawiają się tylko pod `ai_notes`. Akceptowane są również jawne potrzeby:
`"needs": ["labs:4548-4", "vitals:trend:85354-9", "timeline:180d"]`.

## 8. Standardy

- `GET /fhir/R4/Patient/{id}/$summary` zwraca dokument International Patient Summary w formacie Bundle.
- `POST /fhir/R4/Observation/$validate?profile=eu-lab` raportuje, jak wynik laboratoryjny wypada w porównaniu z profilem wyniku HL7 Europe Laboratory Report 2.1.0 (błędy, ostrzeżenia, informacje): kategoria, kod (preferowany LOINC), podmiot, czas obowiązywania, wykonawca i wartość, chyba że wynik jest tylko zarejestrowany lub anulowany.
- `GET /v1/terminology/loinc?q=hba1c` przeszukuje połączony podzbiór LOINC, a `GET /v1/search?q=metformin` katalog objawów, schorzeń i leków; obserwacje utworzone bez nazwy wyświetlanej automatycznie otrzymują nazwę LOINC.

## 9. Zgoda pacjenta (OAuth 2.1 + SMART on FHIR)

Klucze API widzą pacjentów utworzonych przez Twój projekt. Aby uzyskać dostęp do istniejącego rekordu osoby, poproś ją o:

1. Zarejestrowanie aplikacji: `POST /admin/projects/{id}/applications` z Twoim URI przekierowania
   (`public` dla aplikacji mobilnych/webowych z PKCE, `confidential` dla serwerów; sekret jest wyświetlany raz).
2. Przekierowanie osoby na stronę zgody:
   `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`
   Osoba loguje się do Anpheros, widzi, o co prosisz, w języku prostym, wybiera rekord (własny,
   należący do osoby zależnej lub ten, który Twoja aplikacja utworzyła dla niej) i jak długo trwa dostęp.
3. Wymiana kodu: `POST /oauth/token` (`authorization_code` + `code_verifier`). Otrzymujesz
   token dostępu (30 min), token odświeżania (30 dni, rotowany przy użyciu) i identyfikator pacjenta.
4. Wywołanie API z `Authorization: Bearer at_…`. Widzisz tylko tego pacjenta, tylko typy zasobów
   i akcje w zakresach; odczyty poza zakresem odpowiadają `403`, wyszukiwania są filtrowane.

Osoba może w każdej chwili odwołać zgodę z poziomu Anpheros; następne wywołanie odpowie `401`. Każde przyznanie jest
odzwierciedlone jako zasób FHIR `Consent`, a każdy dostęp w jego ramach jest rejestrowany i widoczny dla
osoby. Odkrywanie: `/.well-known/smart-configuration`.

## 10. Webhooki

Niech platforma wywoła Ciebie zamiast odpytywania:

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

Zachowaj `secret` z odpowiedzi i weryfikuj `Anpheros-Signature` przy każdej dostawie
(`verifyWebhookSignature` w obu SDK). Zdarzenia zawierają identyfikatory i wersje, a nie dane kliniczne.
Szczegóły, ponawianie prób i przykłady: [webhooks.md](https://developers.anpheros.com/pl/guides/webhooks).

## 11. Organizacje i praktycy

Kliniki, laboratoria i pracujący w nich ludzie to zasoby pierwszej klasy: `Organization`,
`Practitioner`, `PractitionerRole`. Są to zasoby typu **katalog**: żaden pacjent, czytelny dla
każdego projektu w tym samym środowisku, modyfikowalny tylko przez projekt, który je utworzył.

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

Nazwij praktyka stojącego za zapisem za pomocą `X-Anpheros-Author-Ref: Practitioner/<id>` (lub
`PractitionerRole`, `Organization`, `Device`): wygenerowany przez serwer Provenance będzie zawierał
`agent.who.reference`, a `GET /fhir/R4/Provenance?agent=Practitioner/<id>` wymieni wszystko,
co ta osoba zapisała. Wyszukiwanie: `Organization?name=`, `?identifier=`, `?type=`, `Practitioner?name=`,
`?family=`, `?given=`, `PractitionerRole?practitioner=`, `?organization=`, `?role=`, `?specialty=`, `?active=`.

Kto stoi za Twoją aplikacją? Wyślij `X-Anpheros-Acting-As: PractitionerRole/<id>` (lub
`Practitioner/<id>`) w dowolnym zapytaniu `/v1` lub `/fhir/R4` wykonanym z kluczem projektu. Osoba musi
istnieć w katalogu i być aktywna. Odniesienie jest zapisywane w dzienniku dostępu, staje się autorem
zapisów tego zapytania (chyba że ustawisz `X-Anpheros-Author-Ref`) i jest wyświetlane pacjentowi
pod nazwą w jego połączeniach ("Dr Ana Popescu · Clinica Dente odczytała Twoje wyniki laboratoryjne").

## 12. Raporty laboratoryjne w jednym wywołaniu

Wyślij cały raport laboratoryjny (CSV, HL7 v2 ORU^R01 lub JSON) i uzyskaj obserwacje laboratoryjne z kodami LOINC
i zakresami referencyjnymi; ponowne wysyłanie jest bezpieczne. Szczegóły: [lab-connector.md](https://developers.anpheros.com/pl/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
```

## Informacja zwrotna dotycząca zgodności przy zapisach

Każdy `POST`/`PUT` zasobu klinicznego jest sprawdzany pod kątem zgodności z profilem IPS jego sekcji, a w przypadku obserwacji laboratoryjnych – z zasadami raportowania laboratoryjnego HL7 Europe. Zapis nigdy nie jest odrzucany z powodów profilu (błędy strukturalne FHIR nadal są odrzucane); gdy czegoś brakuje, odpowiedź zawiera

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

Popraw to, co jest nazwane, a zasób zostanie uwzględniony w `$summary` pacjenta. Typy zasobów dodane 22 września 2026 r.: `Immunization`, `MedicationAdministration` (wyszukiwanie `statement=MedicationStatement/{id}`), `RelatedPerson`, `QuestionnaireResponse`, `Basic`. Zapisy dokonane przez inne projekty w rekordzie, który można zobaczyć, przychodzą jako zdarzenia webhook z `data.external = true` — zobacz [`docs/webhooks.md`](https://developers.anpheros.com/pl/guides/webhooks).
