Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Webhooks
Événements signés, réessayés, fins pour les écritures de ressources, les changements de consentement et les documents finalisés, avec vérification de signature en TypeScript, Dart et Python.
La plateforme Anpheros peut appeler votre serveur lorsqu'un événement se produit dans votre projet : une ressource a été écrite, une personne a accordé ou révoqué l'accès, un document a été finalisé. Les événements sont légers : identifiants, type, version — jamais de contenu clinique. Lisez la ressource via l'API si vous en avez besoin. Chaque livraison est signée ; vérifiez la signature avant de lui faire confiance.
Enregistrer un point de terminaison
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"}'
La réponse contient secret (whsec_…) une seule fois. Stockez-le ; vous en aurez besoin pour vérifier les signatures.
events accepte ["*"] ou l'un des éléments suivants :
| type | quand | data |
|---|---|---|
resource.created / resource.updated / resource.deleted |
votre projet a écrit une ressource FHIR (REST v1, API FHIR ou un bundle) — ou un autre projet a écrit dans un enregistrement auquel vous avez accès (vous avez créé le patient, ou vous détenez une autorisation active) ; alors data.external est true et data.source indique qui a écrit : author_type (patient / praticien / appareil / import / ia), organization (le nom d'affichage au nom duquel l'auteur a agi), practitioner (nom du répertoire, lorsque connu), source_system |
resource_type, id, patient (l'identifiant que vous voyez), version, last_updated, et pour les écritures externes external, source |
consent.granted |
une personne a accordé à votre application l'accès depuis la page de consentement (ou une application de confiance a lié son enregistrement) | grant_id, patient, application_id, scopes, purpose, expires_at |
consent.revoked |
la personne (ou la plateforme) a mis fin à une autorisation | identique à ci-dessus plus revoked_at, reason |
document.finalized |
un téléchargement de document a été finalisé et sa somme de contrôle vérifiée | id, patient, content_type, size, sha256 |
proposal.created |
un agent IA a proposé une écriture dans un enregistrement que vous pouvez voir ; cela attend l'approbation de la personne | id, patient, action, resource_type |
ping |
vous avez demandé une livraison de test | endpoint |
Les points de terminaison sont par projet et par environnement : une clé sk_test_ gère les points de terminaison sandbox,
une clé sk_live_ les points de terminaison de production. Les URL doivent être des points de terminaison publics https://. L'enregistrement (et tout changement ultérieur de url) refuse les adresses locales, privées, link-local, de métadonnées et autres adresses réservées — localhost, 127.0.0.1, ::1, 10.0.0.0/8, 192.168.0.0/16, fd00::/8 et similaires — ainsi que les noms qui s'y résolvent, avec 400 invalid sur le champ url ; cela s'applique également dans le sandbox. Chaque livraison vérifie à nouveau l'adresse et ne se connecte qu'aux adresses IP qu'elle vient de vérifier, de sorte qu'un nom qui pointe plus tard vers un réseau privé (détournement DNS) ne reçoit rien. Pour recevoir des événements sur votre propre machine pendant le développement, exposez-la via un tunnel HTTPS public et enregistrez l'adresse du tunnel.
Jusqu'à 10 points de terminaison par projet et par environnement.
La livraison
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":"…"}}
Répondez avec tout 2xx dans les 10 secondes. Tout le reste (ou un délai d'attente) est un échec et la
livraison est retentée avec un backoff jusqu'à 24 heures (10 tentatives), puis marquée exhausted.
Les livraisons sont "au moins une fois" et peuvent arriver dans le désordre : utilisez Anpheros-Event-Id pour
la déduplication et data.version pour ignorer les mises à jour obsolètes.
Vérifier la signature
v1 est HMAC-SHA256 avec votre secret sur <t>.<raw body> ; rejeter si t a plus de 5 minutes.
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"])
Opérer
GET /v1/webhooks/{id}/deliveries?status=failed— le journal, le plus récent en premier, avec le code de statut et l'erreur.POST /v1/webhooks/{id}/deliveries/{delivery_id}/redeliver— renvoyer un maintenant.POST /v1/webhooks/{id}/ping— un événement de test.POST /v1/webhooks/{id}/rotate— nouveau secret (l'ancien s'arrête immédiatement ; mettez à jour votre serveur d'abord si vous ne pouvez pas vous permettre une interruption : enregistrez un deuxième point de terminaison, puis supprimez l'ancien).PATCH /v1/webhooks/{id}avec{"active": false}met les livraisons en pause ; les livraisons en attente sont supprimées lorsque vous supprimez le point de terminaison.
Les deux SDK exposent ceci sous 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