The platform attempts each event it records for an endpoint at least once, and can send one event more than once. A Replay sends an earlier outcome again under a new event id. Automatic delivery stops at a terminal failure or after three days, and the platform records no events for an endpoint while it is switched off. Endpoint registration and signature verification are in the setup guide.
Outcome model
An API response that accepts a write request does not mean the transaction is final on chain. Many write routes queue the transaction, so the response confirms only that the platform accepted the instruction. The lifecycle state of an event tells you how far the fact has progressed. The lifecycle page defines each state. The idempotency and async settlement guide covers the write response.
A chain reorganisation replaces recent blocks with a competing set of blocks. The platform sends a final event for a chain log only after the block passes the network's finality depth, which Lifecycle states defines.
Identifiers and deduplication
Verify the exact raw body and its signature before trusting an event or using its identifiers. The setup guide documents verification. A lost response can cause a duplicate delivery, so a successful verification does not mean the event is new.
The platform adds the headers webhook-delivery-id and webhook-endpoint-id to the three headers of the open Standard Webhooks specification: webhook-id, webhook-timestamp and webhook-signature. The webhook-endpoint-id header names your endpoint and stays the same for it. The setup guide lists every header.
Deduplicate deliveries on webhook-id. A retry, a Resend, and a send that the platform repeats when it stopped before recording the attempt all keep the webhook-id of the first attempt. Answer a webhook-id you already handled with a 2xx response.
A Replay is a new event with a new evt_id, so webhook-id does not match it. Its source_id and its payload identifiers match the original. When you recover through a Replay, deduplicate outcomes on source_id, or on payload identifiers such as the transactionHash and logIndex of a token transfer.
For each endpoint, the platform stores at most one event with a given source_id, excluding Replay and test events. A provisional event and the final event for the same fact have different source_id and evt_id values, because the source_id includes the event name and version. Match them through the payload identifiers.
The optional request.idempotency_key is a correlation field, not a delivery deduplication key. A chain-sourced event includes the caller's key when the transaction can be attributed to one organisation and one nonempty caller key, and that organisation owns the endpoint. Conflicting attribution, a missing key or an endpoint in another organisation leaves the field absent. A Replay or retraction preserves a key already present in the stored event. When the field is absent, correlate through the payload identifiers rather than inventing a key.
The helper verifyWebhook in @settlemint/ accepts an optional replayStore. With a store, it claims the webhook-id of each delivery whose signature verifies and returns REPLAYED_EVENT for an id that is already claimed. Answer REPLAYED_EVENT with a 2xx response. When your handler fails, call release on the verified result, so the platform's retry of that webhook-id verifies again. Your store must claim each id in one atomic write. Refuse a repeated delivery in the setup guide explains the store methods and the cases a store does not cover.
Ordering
The platform assigns each event a position in its endpoint's delivery sequence. A later eligible event waits while an earlier event remains pending, including during backoff. A successful attempt, a terminal failure, or exhaustion of the retry window releases the later events. A missing counter-signed receipt can reopen an event for retry.
A linked correction waits for its cause. The platform sends it after the event it replaces is delivered, or after that event can no longer be delivered. This permits a correction to identify an event your system never received.
The platform gives no guarantee of:
- Order between endpoints. Each endpoint has its own sequence.
- Delivery of a chain
finalevent before the events recorded after it. An event that waits for chain finality does not hold back later events, so its delivery can follow theirs.
A Replay takes the next place in the endpoint's sequence, after every event the platform already recorded.
Retries
Your response decides what the platform does next.
The receipt rules also apply after a 2xx response when receipts are enabled.
When your receiver cannot process an event at that moment, answer 503 or 429, not another 4xx. A 4xx ends delivery of the event, and only a Resend recovers it.
The platform also checks the endpoint address before each attempt. When the address falls outside the destination policy, for example because its hostname now resolves to a private address, the platform sends nothing. It marks the attempt TARGET_REFUSED, does not retry, and ends delivery of the event. Correct the endpoint URL, then use Resend.
The platform waits before each retry. The base wait doubles with each failed attempt: 30 seconds after attempt 1, 60 seconds after attempt 2, 2 minutes after attempt 3, and so on, limited only by the retry window. The platform multiplies the base wait by a random factor from 0.7 to 1.3. When a failed response carries a Retry-After header, the platform waits at least that long. The wait never exceeds the time left in the retry window. An attempt times out after 20 seconds.
The retry window is three days. It starts when the platform records the event, not at the first attempt.
At exhaustion, the platform abandons automatic delivery, writes a warning log, and records a failed trace span. Later eligible events can proceed. The recorded attempts remain available in the endpoint's delivery history, under Event deliveries in the Console. A terminal failure also stops automatic delivery. Resend and Replay provide recovery actions after the receiver is repaired.
A run of failed attempts can also switch the endpoint off. After 30 consecutive failed attempts, test events excluded, the platform opens the endpoint's circuit breaker and switches the endpoint off. The platform queues no new events for an endpoint that is off, and no Replay recovers them later. It probes the endpoint and resumes delivery after two successful probes. Enabling the endpoint with PATCH /api/ and disabled: false resets the breaker at once. The Webhook Delivery concept describes the circuit breaker in full.
Resend and replay
Resend and Replay are authenticated Platform API requests. The authentication guide describes the accepted credentials. The v2 API reference defines their request, response and error bodies. The event-delivery signing secret is not a replacement for API authentication.
Both actions send an event again. They differ in what they keep.
A Resend queues one more attempt. It runs even when an earlier attempt succeeded, so your endpoint can receive an event it already acknowledged. The call returns deliveryId and scheduled. The value scheduled is false, and the platform changes nothing, when any of these holds:
- The attempt is not the latest attempt of its event.
- The event was replaced or cancelled after a chain reorganisation, so the platform no longer delivers it.
- A newer attempt is already claimed, or an earlier Resend has not produced an attempt.
A retry waiting in backoff does not block a Resend.
A Resend does not restart the retry window. The platform measures the window from when it recorded the event. A failed Resend attempt on an event older than three days gets no retry.
A Replay takes either a block range or one event. The block range holds fromBlock, an optional toBlock, and chainId. Without toBlock, the range ends at the highest block of an event recorded for the endpoint on that chain. The single event holds evtId and an optional chainId. The response returns replayId, eventsEnqueued and snapshotToBlock, the last block the range covered. The platform resends the stored payload with its lifecycle state, so a replayed provisional event is still provisional.
Do not use Replay arrival order or a global ranking of lifecycle_state values to replace a business record. Follow the event family's correlation and transition rules in the catalogue. A replayed provisional transfer does not undo its final confirmation. Retain explicit supersedes relationships so that an older observation cannot restore a fact already withdrawn. If the Replay's relationship to your record is unclear, reconcile the resource before overwriting that record.
A Replay is subject to these rules:
- The platform rejects it while the endpoint is switched off or its circuit breaker is open.
- A range whose
toBlockis before itsfromBlockis rejected withWEBHOOK_.REPLAY_ RANGE_ REVERSED - A range wider than 10,000 blocks needs
confirmLargeRangeset totrue. Without it, the platform rejects the range withWEBHOOK_.REPLAY_ RANGE_ TOO_ LARGE - A
chainIdthe organisation has no network for is rejected withWEBHOOK_, before anything is queued. A network that the organisation registered can still be replayed after it is turned off.REPLAY_ CHAIN_ NOT_ AVAILABLE - An organisation can start at most 10 Replays per minute on each API server, because each server counts its own requests.
- The platform does not replay an event that a chain reorganisation replaced or cancelled.
If a Replay response is lost, repeating the request can queue the same outcomes again with new event ids. Deduplicate those outcomes by source_id, and do not assume the second request repeats the first response. The Resend conditions still apply to its original deliveryId. Treat neither Resend nor Replay as safe to repeat after an API failure.
Chain of custody
GET /api/ returns the recorded dispatch history of one event. The record is the platform's own account of what it sent. It is not signed, it is stored with the event, and the retention cleanup deletes it 30 days after delivery ends. Keep your own copy of evidence you must retain, or enable counter-signed receipts. The route needs webhook management permission. The Console shows the same record under “Chain of custody” in the “Webhook event” sheet.
A hop's contentHash equals the body hash a counter-signed receipt submits for the same body, so the two records can be matched. An event with no successful attempt has no hops.
Delivery history retention
The platform periodically deletes settled delivery history more than 30 days old. It measures the age from when delivery ended, not from when the event was recorded. The event's delivery attempts and counter-signed receipts are removed with it.
This cleanup includes final and retracted events. It also includes provisional events recorded inside the platform, such as trading- and trading-: those events do not become final. Pending deliveries, test events and provisional observations from chain logs are outside this cleanup.
The 30-day retention period does not extend the three-day retry window. Keep your receiver's business records and acknowledgements for as long as your audit policy requires. The platform's delivery history is not a permanent archive.
Counter-signed receipts
The platform signs each delivery over webhook-id, webhook-timestamp and the exact body, as the setup guide describes. A 2xx response records that your endpoint answered. A counter-signed receipt records your system's acknowledgement of the exact body, signed with the endpoint's webhook signing secret. The endpoint setting counterSignedReceipts enables this acknowledgement. Enable it when you must show that your system, not only a proxy in front of it, accepted the exact body. Your receiver then posts a receipt within the receipt window after each 2xx response, or the platform retries the event. After a successful attempt, the platform schedules a deadline for the receipt.
Receipt submission requires Platform API authentication as well as the consumer signature. The v2 API reference defines the request and response contract for POST /api/.
A successful submission returns the receipt resource. A repeated valid submission within the receipt window updates the receipt for that delivery, including its verification timestamp. The response need not be identical. A delivery already marked as receipt-timed-out is rejected rather than reopened.
You post the receipt to POST /api/ with deliveryId, evtId, endpointId, consumerSignature and innerEventHash. The platform accepts a valid signature made with the endpoint's active secret or its previous secret during rotation. The signing string has five lines, joined with \n, with no trailing newline.
SHA-256 means Secure Hash Algorithm 256. The receipt signature is a keyed-hash message authentication code (HMAC) with SHA-256 over the signing string, written in hexadecimal. The key is the endpoint signing secret without its dalp_whsk_ prefix, decoded from base64. The SDK functions signWebhookReceipt and build in @settlemint/ produce the signature and the string.
The receipt window is 30 seconds by default. The endpoint field receiptTimeoutSeconds sets it to a whole number from 1 to 60. The window starts after your 2xx response.
An invalid signature rejects the receipt submission without settling the event or scheduling a new delivery. Correct the signature and submit it again while the receipt window is open. If no valid receipt arrives by the deadline, the receipt-timeout path retries delivery within the event's retry window.
A correctly signed receipt with the right hash can still replace a hash-mismatched receipt for the same delivery. The platform then records the receipt and restores the attempt as delivered, as long as the attempt has no recorded receipt timeout.
GET /api/ lists the stored receipts, and GET /api/ reads one. Both need webhook management permission. A receipt submission for a delivery that did not require a receipt when the platform sent it answers status 404 with WEBHOOK_.
A late submission does not reopen its receipt window or schedule another attempt. Submit a receipt for the next delivery if the platform retries it. A rejected receipt submission and a retry of the webhook delivery are separate operations.
Payload shape
Use the machine-readable event definitions or the SDK's Webhook types for each event's envelope and payload schema. Those schemas do not hold the consent field-path list.
Each endpoint has a payload shape. The shape controls whether the personal data fields of an event reach your endpoint. Each event defines its own personal data fields, such as the payer address of a trade fee.
A removed field is absent from the payload. It is not null, so read personal data fields as optional. The platform shapes the payload when it records the event for the endpoint. A later change of shape affects new events only, and a Replay sends the stored payload.
The platform rejects a request that creates an endpoint as fat. A switch to fat needs fat to list every personal data field of the events the subscriptions match, written as <eventType>.<fieldPath>. The list includes the fields of the retractions of those events. A list that misses a field is rejected with status 422 and the error WEBHOOK_, id DALP-0517. The same check runs when an update changes the subscriptions of a fat endpoint. The platform records who acknowledged the fields, and when.
The Console endpoint editor prepares and records the required acknowledgement for the selected subscriptions. An endpoint read returns its stored fat, not a computed list for a proposed subscription change. The event manifest and the public DALP-0517 error body do not supply that complete consent list. Do not infer consent paths from a sample payload.
Retractions
A retraction withdraws an earlier reported fact. When present, supersedes holds the evt_id of the event it replaces. The named event can be one your endpoint never received.
- After a chain reorganisation removes a block, the platform retracts only an event for which it recorded a successful delivery to your endpoint. Otherwise, it cancels the event and sends no retraction.
- For committed-state retractions such as
trading-, the platform looks up the earlier event id created for your endpoint. This lookup does not require a successful delivery. Thevenue. trade- settled. retracted supersedesfield is absent when no earlier endpoint event id exists, for example because the endpoint did not exist. - When the platform recorded the earlier event but could not deliver it, the retraction names an event you never received. The platform sends the retraction once the earlier event can no longer be delivered.
Your handler can have applied a chain observation even when its HTTP acknowledgement was lost. Without a recorded successful delivery, the platform can cancel that observation without sending a retraction. Absence of a correction is therefore not confirmation of the canonical chain state. Keep uncertain effects provisional and reconcile them before confirming your business record.
Consumer handling follows these rules:
- Match by
supersedes. If it is absent or unknown, use the payload identifiers, such astradeId. Reverse only effects your system applied. - Retain the retraction and audit-log any unknown
supersedesreference. An unknown reference alone is not a processing failure. Do not invent a reversal for an action your system never applied. - Keep the superseding state if the original arrives later. A Replay can deliver an older observation after a newer one.
The .retracted name suffix does not always mean a retracted lifecycle state. For example, token. has state final and no envelope supersedes link. Match this event through its payload identifiers. Read the event's type as well as lifecycle_state.
The lifecycle state recalled is reserved. The platform sends no new event with this state, and a Replay resends one only when DALP 3.1 stored it. Acknowledge such an event and change nothing.
Related
- Event catalogue: the events of every domain except token sales, trading venues and XvP settlements, when the platform sends each one and what to do with it.
- Market and settlement events: the events of token sales, trading venues and XvP settlements, when the platform sends each one and what to do with it.
- Lifecycle states: what each state means, with worked sequences.
- Subscriptions: the patterns that select events, and the events the default subscriptions skip.
- Setup guide: endpoint registration, headers and signature verification.
- Webhook Delivery: the delivery model and endpoint recovery.