Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Вебхуки
Підписані, повторювані, тонкі події для запису ресурсів, змін згоди та фіналізованих документів, з перевіркою підпису на TypeScript, Dart та Python.
Платформа Anpheros може викликати ваш сервер, коли щось відбувається у вашому проєкті: ресурс було записано, особа надала або відкликала доступ, документ було фіналізовано. Події є мінімальними: ідентифікатори, тип, версія — ніколи клінічний вміст. Читайте ресурс через API, якщо він вам потрібен. Кожна доставка підписана; перевіряйте підпис перед тим, як йому довіряти.
Зареєструйте кінцеву точку
curl -X POST $BASE/v1/webhooks -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"url": "https://your.app/anpheros/hook", "events": ["resource.created", "consent.revoked"], "description": "prod"}'
Відповідь містить secret (whsec_…) один раз. Збережіть його; він вам знадобиться для перевірки підписів.
events приймає ["*"] або будь-який з наступних:
| тип | коли | data |
|---|---|---|
resource.created / resource.updated / resource.deleted |
ваш проєкт записав ресурс FHIR (REST v1, FHIR API або бандл) — або інший проєкт записав у запис, до якого ви маєте доступ (ви створили пацієнта або маєте активний дозвіл); тоді data.external дорівнює true, а data.source вказує, хто це записав: author_type (пацієнт / практикуючий лікар / пристрій / імпорт / ШІ), organization (відображувана назва, від імені якої діяв автор), practitioner (назва з каталогу, коли відома), source_system |
resource_type, id, patient (ідентифікатор, який ви бачите), version, last_updated, а для зовнішніх записів external, source |
consent.granted |
особа надала вашому додатку доступ зі сторінки згоди (або довірений додаток пов'язав свій запис) | grant_id, patient, application_id, scopes, purpose, expires_at |
consent.revoked |
особа (або платформа) припинила дію дозволу | так само, як вище, плюс revoked_at, reason |
document.finalized |
завантаження документа було завершено та перевірено за контрольними сумами | id, patient, content_type, size, sha256 |
proposal.created |
агент ШІ запропонував записати дані до запису, який ви можете бачити; очікує на схвалення особи | id, patient, action, resource_type |
ping |
ви запросили тестову доставку | endpoint |
Кінцеві точки є для кожного проєкту та середовища: ключ sk_test_ керує кінцевими точками пісочниці,
ключ sk_live_ — виробничими. URL-адреси повинні бути загальнодоступними кінцевими точками https://. Реєстрація (і будь-яка подальша зміна url) відхиляє локальні, приватні, link-local, метадані та інші зарезервовані адреси — localhost, 127.0.0.1, ::1, 10.0.0.0/8, 192.168.0.0/16, fd00::/8 і подібні — а також імена, що розв'язуються до них, з 400 invalid у полі url; це застосовується і в пісочниці. Кожна доставка повторно перевіряє адресу та підключається лише до IP-адрес, які вона щойно перевірила, тому ім'я, яке пізніше вказує на приватну мережу (DNS rebinding), нічого не отримає. Щоб отримувати події на своїй машині під час розробки, виставте її через загальнодоступний HTTPS-тунель і зареєструйте адресу тунелю.
До 10 кінцевих точок на проєкт та середовище.
Доставка
POST https://your.app/anpheros/hook
Content-Type: application/json
User-Agent: Anpheros-Webhooks/1.0
Anpheros-Event: resource.created
Anpheros-Event-Id: evt_…
Anpheros-Delivery: whd_…
Anpheros-Signature: t=1789800000,v1=5f3a…
{"id":"evt_…","type":"resource.created","created_at":"2026-09-19T12:00:00.000Z","environment":"production",
"project":"proj_…","data":{"resource_type":"Observation","id":"…","patient":"…","version":1,"last_updated":"…"}}
Відповідайте будь-якими 2xx протягом 10 секунд. Будь-що інше (або тайм-аут) вважається помилкою, і доставка буде повторена з експоненційним відкотом до 24 годин (10 спроб), після чого буде позначена як exhausted.
Доставки є "принаймні один раз" (at-least-once) і можуть надходити не по порядку: використовуйте Anpheros-Event-Id для
дедуплікації та data.version для ігнорування застарілих оновлень.
Перевірка підпису
v1 — це HMAC-SHA256 із вашим секретом над <t>.<raw body>; відхилити, якщо t старше 5 хвилин.
import { verifyWebhookSignature } from '@anpheros/sdk';
app.post('/anpheros/hook', express.raw({ type: 'application/json' }), async (req, res) => {
const ok = await verifyWebhookSignature({ secret: process.env.ANPHEROS_WEBHOOK_SECRET!, header: req.header('anpheros-signature'), body: req.body });
if (!ok) return res.status(400).end();
const event = JSON.parse(req.body.toString());
// … enqueue and return quickly
res.status(204).end();
});
import 'package:anpheros_sdk/anpheros_sdk.dart';
final ok = verifyWebhookSignature(secret: secret, header: request.headers['anpheros-signature'], body: rawBodyBytes);
import hmac, hashlib, time
def verify(secret: str, header: str, body: bytes, tolerance=300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
Експлуатація
GET /v1/webhooks/{id}/deliveries?status=failed— журнал, найновіші спочатку, з кодом статусу та помилкою.POST /v1/webhooks/{id}/deliveries/{delivery_id}/redeliver— надіслати ще раз зараз.POST /v1/webhooks/{id}/ping— тестова подія.POST /v1/webhooks/{id}/rotate— новий секрет (старий негайно припиняє діяти; оновіть свій сервер спочатку, якщо не можете дозволити собі перерву: зареєструйте другий кінцевий пункт призначення, потім видаліть старий).PATCH /v1/webhooks/{id}з{"active": false}призупиняє доставку; очікуючі будуть відкинуті, коли ви видалите кінцевий пункт призначення.
Обидва SDK надають це під webhooks (create, list, get, update, delete, rotateSecret, ping, deliveries, redeliver).
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card