Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Webhooks
Podepsané, opakované, tenké události pro zápisy zdrojů, změny souhlasu a finalizované dokumenty, s ověřením podpisu v TypeScript, Dart a Python.
Platforma Anpheros může zavolat váš server, když se ve vašem projektu něco stane: byl zapsán zdroj, osoba udělila nebo odvolala přístup, byl finalizován dokument. Události jsou tenké: id, typ, verze — nikdy klinický obsah. Přečtěte si zdroj přes API, pokud jej potřebujete. Každé doručení je podepsáno; ověřte podpis předtím, než mu důvěřujete.
Registrace koncového bodu
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"}'
Odpověď obsahuje secret (whsec_…) jednou. Uložte si ji; budete ji potřebovat k ověření podpisů.
events přijímá ["*"] nebo kteroukoli z následujících možností:
| typ | kdy | data |
|---|---|---|
resource.created / resource.updated / resource.deleted |
váš projekt zapsal FHIR zdroj (REST v1, FHIR API nebo bundle) — nebo jiný projekt zapsal do záznamu, ke kterému máte přístup (vytvořili jste pacienta nebo držíte aktivní oprávnění); pak data.external je true a data.source říká, kdo to zapsal: author_type (pacient / praktikant / zařízení / import / AI), organization (zobrazovaný název, za který se pisatel jednal), practitioner (název z adresáře, pokud je znám), source_system |
resource_type, id, patient (ID, které vidíte), version, last_updated a pro externí zápisy external, source |
consent.granted |
osoba udělila vaší aplikaci přístup ze stránky souhlasu (nebo důvěryhodná aplikace propojená s jejím záznamem) | grant_id, patient, application_id, scopes, purpose, expires_at |
consent.revoked |
osoba (nebo platforma) ukončila oprávnění | stejné jako výše plus revoked_at, reason |
document.finalized |
nahrání dokumentu bylo dokončeno a zkontrolováno pomocí checksum | id, patient, content_type, size, sha256 |
proposal.created |
agent AI navrhl zápis do záznamu, který vidíte; čeká na schválení osoby | id, patient, action, resource_type |
ping |
požádali jste o testovací doručení | endpoint |
Koncové body jsou na projekt a prostředí: klíč sk_test_ spravuje sandbox koncové body,
klíč sk_live_ produkční koncové body. URL adresy musí být veřejné https:// koncové body. Registrace (a jakákoli pozdější změna url) odmítá lokální, privátní, link-local, metadata a další rezervované adresy — localhost, 127.0.0.1, ::1, 10.0.0.0/8, 192.168.0.0/16, fd00::/8 a podobné — a názvy, které na ně odkazují, s 400 invalid na poli url; to platí i v sandboxu. Každé doručení znovu zkontroluje adresu a připojí se pouze k IP adresám, které právě zkontrolovalo, takže název, který později ukazuje do privátní sítě (DNS rebinding), nic nedostane. Chcete-li přijímat události na svém vlastním stroji během vývoje, vystavte jej prostřednictvím veřejného HTTPS tunelu a zaregistrujte adresu tunelu.
Až 10 koncových bodů na projekt a prostředí.
Doručení
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":"…"}}
Odpovězte jakýmikoli 2xx do 10 sekund. Cokoli jiného (nebo vypršení časového limitu) je chyba a doručení se opakuje s postupným navyšováním zpoždění po dobu až 24 hodin (10 pokusů), poté je označeno jako exhausted.
Doručení jsou "alespoň jednou" (at-least-once) a mohou přijít mimo pořadí: použijte Anpheros-Event-Id pro
deduplikaci a data.version pro ignorování zastaralých aktualizací.
Ověření podpisu
v1 je HMAC-SHA256 s vaším tajným klíčem nad <t>.<raw body>; odmítněte, pokud je t starší než 5 minut.
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"])
Provoz
GET /v1/webhooks/{id}/deliveries?status=failed— protokol, nejnovější první, s kódem stavu a chybou.POST /v1/webhooks/{id}/deliveries/{delivery_id}/redeliver— odešlete jeden znovu nyní.POST /v1/webhooks/{id}/ping— testovací událost.POST /v1/webhooks/{id}/rotate— nové tajné klíčové slovo (staré přestane fungovat okamžitě; nejprve aktualizujte svůj server, pokud si nemůžete dovolit mezeru: zaregistrujte druhý koncový bod, poté smažte starý).PATCH /v1/webhooks/{id}s{"active": false}pozastaví doručování; čekající položky budou zrušeny, když smažete koncový bod.
Obě SDK toto zpřístupňují pod 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