Receive webhooks
Return to the full receiver flow and follow-up pattern.
Webhooks
Validate ChartHero webhook headers, timestamps, and HMAC signatures.
Available for activated subscriptionsVerify webhook signatures before parsing trusted business fields or fetching clinical follow-up resources. The check proves the delivery was signed with the endpoint signing secret and that the timestamp is within the documented tolerance.
This page covers verification only. For the full receiver workflow, see Receive webhooks.
Signature verification does not use ChartHero API-key scopes. It requires the endpoint signing secret and these webhook headers:
| Header | Purpose |
|---|---|
ChartHero-Event-Id |
Business idempotency key that must match body id. |
ChartHero-Delivery-Id |
Stable delivery identifier for support/debug metadata. |
ChartHero-Timestamp |
Decimal Unix epoch seconds used in the signature input. |
ChartHero-Signature |
v1= HMAC-SHA256 digest for the delivery. |
ChartHero-Webhook-Version |
Webhook version that must match body api_version. |
Reject requests with missing headers, malformed timestamps, unsupported signature versions, or timestamps outside the allowed tolerance.
Example signed delivery inputs:
curl -X POST "https://partner.example.test/chart-hero/webhooks" \
-H "Content-Type: application/json" \
-H "ChartHero-Event-Id: evt_recording_transcript_ready_01" \
-H "ChartHero-Delivery-Id: whd_recording_transcript_ready_01" \
-H "ChartHero-Timestamp: 1777649400" \
-H "ChartHero-Signature: v1=a3bb0750eef64758be4a034aaff5dd5774c21bf7fe25083b51d61ba0214c0419" \
-H "ChartHero-Webhook-Version: 2026-05-01" \
--data-raw '{"id":"evt_recording_transcript_ready_01","type":"recording.transcript_ready","api_version":"2026-05-01","occurred_at":"2026-05-01T15:29:55Z","organization_id":"org_synthetic_webhook_001","resources":{"encounter_id":"enc_synthetic_webhook_001","document_id":"doc_synthetic_transcript_001"}}'
Build the signed payload as {timestamp}.{raw_request_body}. Use the exact body bytes received by the HTTP server, before JSON reserialization or whitespace normalization.
1777649400.{"id":"evt_recording_transcript_ready_01","type":"recording.transcript_ready","api_version":"2026-05-01","occurred_at":"2026-05-01T15:29:55Z","organization_id":"org_synthetic_webhook_001","resources":{"encounter_id":"enc_synthetic_webhook_001","document_id":"doc_synthetic_transcript_001"}}
Compute the HMAC-SHA256 digest with the endpoint signing secret and compare it to the v1 value in ChartHero-Signature using a constant-time comparison.
The signed body is the thin 2026-05-01 pointer payload. This version's fields are exact and do not allow additional properties; it does not embed transcript turns, audio URLs, patient demographics, document content, or clinical payloads.
Language-neutral verification steps:
ChartHero-Timestamp and reject it if it is not decimal Unix epoch seconds.300 seconds from your server clock.{timestamp}.{raw_request_body}.ChartHero-Signature and require the supported v1= value.ChartHero-Event-Id equals body id.ChartHero-Webhook-Version equals body api_version.If verification and lightweight validation succeed, return any HTTP 2xx response. No JSON acknowledgement body is required.
HTTP/1.1 204 No Content
If verification fails, do not process clinical follow-up work. Return a non-2xx response according to your receiver policy.
ChartHero records outbound webhook delivery evidence separately from PHI access audit events. Public API follow-up fetches are separate PHI disclosures audited as public API access.
After the signature is valid, parse the JSON body and verify these consistency checks:
| Header | Body field |
|---|---|
ChartHero-Event-Id |
id |
ChartHero-Webhook-Version |
api_version |
Do not process clinical follow-up work when either check fails.
Other common verification failures include missing headers, unsupported signature versions, non-decimal timestamps, stale timestamps outside the 300 second tolerance, and comparing against a JSON-reserialized body instead of the raw request body.
Return to the full receiver flow and follow-up pattern.
Confirm the webhook headers and attempt model.
Inspect the generated webhook operation.