Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Webhook
リソース書き込み、同意変更、確定済みドキュメントのための署名付き、リトライ付き、軽量イベント。TypeScript、Dart、Pythonでの署名検証。
Anpheros Platform は、プロジェクト内で何かが発生した場合(リソースが書き込まれた、ユーザーがアクセスを許可または拒否した、ドキュメントが最終化されたなど)に、お客様のサーバーを呼び出すことができます。イベントは軽量です。ID、タイプ、バージョンのみを含み、臨床コンテンツは一切含みません。必要に応じて、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 は ["*"] または以下のいずれかを受け付けます。
| type | when | data |
|---|---|---|
resource.created / resource.updated / resource.deleted |
プロジェクトが FHIR リソース (REST v1, FHIR API またはバンドル) を作成した場合 — または、アクセス権のあるレコードに別のプロジェクトが書き込んだ場合 (患者を作成した、またはアクティブなグラントを保持している場合)。この場合、data.external は true となり、data.source は誰が書き込んだかを示します: author_type (patient / practitioner / device / import / ai)、organization (書き込み元が代理した表示名)、practitioner (ディレクトリからの名前、判明している場合)、source_system |
resource_type、id、patient (表示される ID)、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 |
AI エージェントが、表示可能なレコードへの書き込みを提案した場合。個人の承認を待っています | id、patient、action、resource_type |
ping |
テスト配信をリクエストした場合 | endpoint |
エンドポイントはプロジェクトおよび環境ごとです。sk_test_ キーはサンドボックスのエンドポイントを管理し、
sk_live_ キーは本番環境のエンドポイントを管理します。URL は公開されている https:// エンドポイントである必要があります。登録 (および url の後続の変更) では、ローカル、プライベート、リンクローカル、メタデータ、その他の予約済みアドレス — localhost、127.0.0.1、::1、10.0.0.0/8、192.168.0.0/16、fd00::/8 など — およびそれらに解決される名前は拒否されます。これは 400 invalid のフィールド url で行われます。これはサンドボックスでも適用されます。すべての配信はアドレスを再度チェックし、直前にチェックした IP アドレスにのみ接続します。そのため、後でプライベートネットワークを指すようになった名前 (DNS リバインディング) は何も受信しません。開発中に独自のコンピューターでイベントを受信するには、公開 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":"…"}}
10秒以内に、2xx を返してください。それ以外(またはタイムアウト)は失敗とみなし、
最大24時間(10回試行)バックオフしてリトライし、その後 exhausted とマークされます。
デリバリーは少なくとも1回行われ、順不同で到着する可能性があります。重複排除には Anpheros-Event-Id を、
古い更新の無視には data.version を使用してください。
署名の検証
v1 は、<t>.<raw body> に対する秘密鍵を使用した HMAC-SHA256 です。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— 新しいシークレット(古いシークレットは即座に無効になります。ギャップを許容できない場合は、まずサーバーを更新してください。2番目のエンドポイントを登録してから、古いものを削除します)。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