Truemed calls your endpoint when an open dispute’s state or phase changes — for example, after you
submit evidence and it moves to under_review. An update that changes neither state nor phase is
silent.
Authentication: Requests are HMAC-SHA256 signed. The x-truemed-signature header carries a timestamp and
the signature in the form t=<unix-timestamp>,v0=<hex-signature>. Compute HMAC-SHA256 over
<t>.<raw-request-body> with your webhook signing secret and compare the hex digest to v0. Sign the raw body
bytes exactly as received, since re-serializing the JSON changes the bytes and breaks the signature.
The signed body is the standard Truemed envelope:
webhook_delivery_id - Delivery id (dlv_…). Retries of the same event repeat the same value; use it to
deduplicate.event_type - The wire event name (dispute.created, dispute.updated, or dispute.closed).data - The full canonical dispute, the same shape returned by GET /api/v1/disputes/{dispute_id} — including
dispute_id, state, phase, reason, amount, due_by, counters, and metadata. Null fields are
omitted. Payloads carry canonical Truemed fields and the public dispute_id UUID only, never raw processor
shapes. Always key your records on dispute_id.(Unsigned legacy endpoints receive the data object as the flat top-level body, with no envelope and no
event_type.)
The model is notify, then fetch: the snapshot is complete enough to act on directly, and you can re-fetch the dispute for authoritative state when a delivery is delayed or retried out of order.
Inquiries notify too, with one exception. A live inquiry fires dispute.created / dispute.updated just like
a chargeback, so you can respond to pre-empt its escalation. If the bank later drops a surfaced inquiry, the terminal
closed state fires dispute.closed — so dispute.closed marks any terminal outcome, whether a chargeback result
(won / lost / accepted / expired) or a dropped inquiry (closed). The only silent case is an inquiry that
opens and closes between webhook deliveries — already terminal the first time Truemed sees it — which fires no webhook.
Return HTTP 204 with an empty body. Truemed retries failed deliveries with backoff for up to 7 days.
The full canonical dispute — the same shape returned by GET /api/v1/disputes/{dispute_id}.
The event type: dispute.created, dispute.updated, or dispute.closed.
Deterministic idempotency key for this delivery (dlv_…); stable across retries.
Webhook received successfully (HTTP 204 No Content)