# Начало работы

> От API-ключа до чтения и записи записи пациента FHIR R4 в песочнице: ключи, первые вызовы, запись с указанием происхождения, документы, контекст ИИ, IPS, согласие, веб-хуки и лабораторные отчеты.

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

Anpheros Platform — это бэкенд для медицинских данных: запись FHIR R4 на пациента, изоляция проектов,
указание происхождения при каждой записи и простой REST API поверх тех же данных. Это руководство проведет вас
от нуля до чтения и записи записи пациента в песочнице.

Базовый URL (песочница и продакшн используют один и тот же; ключ определяет плоскость данных):

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

Интерактивный справочник: `/docs` (OpenAPI) и `/fhir/R4/metadata` (CapabilityStatement).

## 1. Получите ключ (1 минута)

Песочница предоставляется в режиме самообслуживания. Войдите в панель управления (`https://platform.anpheros.com/dashboard/`)
через Google и нажмите **Получить ключ песочницы**: вы получите организацию, проект песочницы с собственными
синтетическими пациентами и ключ — отображается один раз. То же самое через Admin API, используя ваш токен пользователя 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": {…}}
```

Или пошагово:

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

Вы получите `sk_test_…`. Ключи песочницы видят только данные песочницы. Производственные ключи (`sk_live_…`)
выдаются проверенным организациям с подписанным DPA — напишите на platform@anpheros.com. Песочница бесплатна;
производство начинается с 99 евро в месяц, первый месяц бесплатно (см. [Цены](https://developers.anpheros.com/ru/guides/pricing)).

## 2. Первый вызов (1 минута)

В вашем проекте песочницы уже есть своя копия из 30 синтетических пациентов с шестимесячной историей
до дня создания проекта: взрослые, дети и пожилые люди со всей Европы, с
заболеваниями (ICD-10), лекарствами (ATC), аллергиями, результатами лабораторных исследований и жизненными показателями (LOINC). Копия
принадлежит вашему проекту: изменяйте или удаляйте что угодно — другие проекты этого не увидят. **Сброс тестовых пациентов** на панели управления (или `POST /admin/projects/{id}/sandbox/reset`) возвращает их в исходное состояние
с новыми идентификаторами; пациенты, созданные вами самостоятельно, не затрагиваются. Каждый синтетический пациент сохраняет
стабильный идентификатор при сбросах: `Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02`
всегда является Еленой Ионеску.

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

Лимиты песочницы щедры, но конечны: 10 000 операций записи ресурсов в день на проект, 50 собственных пациентов помимо синтетических, 250 МБ документов (см. [лимиты](https://developers.anpheros.com/ru/guides/limits)).

## 3. Чтение записи

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

Идентификаторы идентичны в `/v1` и `/fhir/R4`; каждый объект v1 несет свою `fhir` ссылку.
`_summary=count` возвращает только общее количество; `_elements=code,effectiveDateTime` возвращает компактные ресурсы с тегом `SUBSETTED`.

## 4. Запись

Укажите автора. `author_type` — это `patient`, `practitioner`, `device`, `import` или `ai`;
если вы его опустите, платформа запишет `import`, но никогда не `patient` по умолчанию.
Записи с `author_type` `ai` соответствуют [HL7 AI Transparency on FHIR](https://build.fhir.org/ig/HL7/aitransparency-ig/):
ресурс несет метку безопасности `AIAST` (*Artificial Intelligence asserted*) и в его Provenance указана причина
`AIAST`, роль агента `Artificial-Intelligence` и профиль `AI-Provenance`. Чтобы назвать модель, зарегистрируйте ее как
`Device` (тип `Artificial-Intelligence`, имя, версия, производитель) и отправьте `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"
}'
```

Ответом является сохраненное наблюдение с `id`, `fhir` и `updated_at`. Повторение точно
такого же запроса с тем же `Idempotency-Key` возвращает тот же ответ и ничего не создает.

## 5. Документы

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

Оригинал никогда не изменяется после этого; `sha256` и `size` записываются, и любые значения, которые вы
позже извлечете, будут ссылаться на документ через `derived_from`.

## 6. Provenance

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

Одна запись на версию: кто (тип автора и проект), когда, из какой исходной системы.

## Важные правила

- **Изоляция**: проект видит созданных им пациентов (плюс общих пациентов песочницы). Пациенты
  других пользователей для вас не существуют: `404`, никогда `403`.
- **Парные идентификаторы**: идентификатор пациента, который вы видите, является вашим. Другой проект
  видит того же человека под другим идентификатором. Свободно сохраняйте наши идентификаторы; никогда не пытайтесь их сопоставить.
- **Происхождение**: каждая запись о записи оставляет ресурс Provenance. Ничто не перезаписывается
  молча; история доступна по адресу `/fhir/R4/{Type}/{id}/_history`.
- **Ошибки**: конечные точки FHIR возвращают `OperationOutcome`; `/v1` и `/admin` возвращают
  `{"error": {"type", "message", "field"}}`. Каждый ответ содержит `Anpheros-Request-Id`; цитируйте его,
  когда пишете нам.
- **Ограничения**: по умолчанию 600 запросов в минуту на ключ, 200 элементов на страницу, 25 МБ на документ.

## 7. Контекст для модели ИИ

Вместо извлечения необработанных записей и принятия решения о том, что соответствует запросу, запросите у платформы контекст:

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

Вы получаете разделы (сводная карточка, состояния, лекарства, аллергии, лабораторные анализы, жизненные показатели с еженедельными тенденциями и маркерами до/после лечения, симптомы, временная шкала, документы), каждый элемент помечен `author_type` и `source`, списком того, что было опущено, чтобы уложиться в бюджет, предупреждениями и `manifest_id`, которая связывает вызов с журналом аудита. Значения, полученные ИИ, никогда не смешиваются с фактами: они появляются только под `ai_notes`. Также принимаются явные запросы:
`"needs": ["labs:4548-4", "vitals:trend:85354-9", "timeline:180d"]`.

## 8. Стандарты

- `GET /fhir/R4/Patient/{id}/$summary` возвращает документ International Patient Summary в формате Bundle.
- `POST /fhir/R4/Observation/$validate?profile=eu-lab` сообщает, как лабораторный результат соотносится с профилем результата HL7 Europe Laboratory Report 2.1.0 (ошибки, предупреждения, информация): категория, код (предпочтительно LOINC), субъект, время действия, исполнитель и значение, если результат только зарегистрирован или отменен.
- `GET /v1/terminology/loinc?q=hba1c` осуществляет поиск по подмножеству LOINC в пакете, а `GET /v1/search?q=metformin` — по каталогу симптомов, состояний и лекарств; наблюдения, созданные без отображаемого имени, автоматически получают имя LOINC.

## 9. Согласие пациента (OAuth 2.1 + SMART on FHIR)

API ключи видят пациентов, созданных вашим проектом. Чтобы получить доступ к существующей записи человека, попросите его:

1. Зарегистрировать приложение: `POST /admin/projects/{id}/applications` с вашим URI перенаправления
   (`public` для мобильных/веб-приложений с PKCE, `confidential` для серверов; секрет отображается один раз).
2. Отправить человека на страницу согласия:
   `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`
   Он входит в Anpheros, видит, что вы запрашиваете, на понятном языке, выбирает запись (свою,
   зависимого или ту, которую ваше приложение создало для него) и определяет срок действия доступа.
3. Обменять код: `POST /oauth/token` (`authorization_code` + `code_verifier`). Вы получаете
   токен доступа (30 минут), токен обновления (30 дней, ротируется при использовании) и идентификатор пациента.
4. Вызывать API с `Authorization: Bearer at_…`. Вы видите только этого пациента, только типы ресурсов
   и действия в рамках областей действия (scopes); запросы на чтение вне областей действия отвечают `403`, поисковые запросы фильтруются.

Человек может отозвать согласие в любое время из Anpheros; следующий вызов ответит `401`. Каждое предоставленное согласие отражается как FHIR ресурс `Consent`, и каждый доступ по нему регистрируется и виден человеку. Поиск: `/.well-known/smart-configuration`.

## 10. Webhooks

Пусть платформа вызывает вас вместо опроса:

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

Сохраняйте `secret` из ответа и проверяйте `Anpheros-Signature` при каждой доставке
(`verifyWebhookSignature` в обоих SDK). События содержат идентификаторы и версии, а не клинические данные.
Подробности, повторные попытки и примеры: [webhooks.md](https://developers.anpheros.com/ru/guides/webhooks).

## 11. Организации и специалисты

Клиники, лаборатории и работающие там люди являются ресурсами первого класса: `Organization`, `Practitioner`, `PractitionerRole`. Это **справочные** ресурсы: не связанные с пациентом, читаемые каждым проектом в одной среде и изменяемые только проектом, который их создал.

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

Укажите специалиста, стоящего за записью, с помощью `X-Anpheros-Author-Ref: Practitioner/<id>` (или `PractitionerRole`, `Organization`, `Device`): сгенерированный сервером Provenance затем будет содержать `agent.who.reference`, а `GET /fhir/R4/Provenance?agent=Practitioner/<id>` перечислит все, что этот человек записал. Поиск: `Organization?name=`, `?identifier=`, `?type=`, `Practitioner?name=`, `?family=`, `?given=`, `PractitionerRole?practitioner=`, `?organization=`, `?role=`, `?specialty=`, `?active=`.

Кто стоит за вашим приложением? Отправьте `X-Anpheros-Acting-As: PractitionerRole/<id>` (или `Practitioner/<id>`) в любом запросе `/v1` или `/fhir/R4`, сделанном с ключом проекта. Специалист должен существовать в справочнике и быть активным. Ссылка записывается в журнал доступа, становится автором записей этого запроса (если вы не установили `X-Anpheros-Author-Ref`) и отображается пациенту по имени в его подключениях ("Д-р Ана Попеску · Клиника Денте прочитала ваши результаты анализов").

## 12. Лабораторные отчеты одним вызовом

Отправьте полный лабораторный отчет (CSV, HL7 v2 ORU^R01 или JSON) и получите лабораторные наблюдения с кодами LOINC и референсными диапазонами; повторная отправка безопасна. Подробности: [lab-connector.md](https://developers.anpheros.com/ru/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
```

## Обратная связь о соответствии при записи данных

Каждый `POST`/`PUT` клинического ресурса проверяется на соответствие профилю IPS для его раздела, а для лабораторных наблюдений — на соответствие правилам HL7 Europe для лабораторных отчетов. Запись никогда не отклоняется по причинам, связанным с профилем (структурные ошибки FHIR по-прежнему приводят к отклонению); когда что-то отсутствует, ответ содержит

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

Исправьте то, что указано, и ресурс будет включен в `$summary` пациента. Типы ресурсов, добавленные 22 сентября 2026 года: `Immunization`, `MedicationAdministration` (поиск `statement=MedicationStatement/{id}`), `RelatedPerson`, `QuestionnaireResponse`, `Basic`. Записи, сделанные другими проектами в запись, которую вы можете видеть, поступают в виде событий веб-перехватчика с `data.external = true` — см. [`docs/webhooks.md`](https://developers.anpheros.com/ru/guides/webhooks).
