Webhook subscription patterns
Lists the subscription pattern grammar, its validation rules, the default subscriptions, and the live events the defaults skip.
A webhook endpoint is the secure web address that receives DALP events. It receives an event when one of its subscription patterns matches the event name. A pattern is an exact name, *, a name prefix ending in .*, or a state pattern such as *.final. This page states the grammar and validation rules, the default subscriptions, and the live events those defaults skip.
Pattern grammar
A pattern has one of four forms. For a new event, the platform matches it against the event name only. An event name has three parts separated by dots, for example token.transfer.final. Many names end in a lifecycle state. Some end in another word, such as funding.requirement.raised.
For a reorg correction, the platform checks whether it recorded a successful delivery of the removed chain observation. Current subscription patterns do not decide whether that automatic correction is generated. Receiver-side processing alone is not a recorded delivery. Your receiver must handle these corrections; the retraction rules cover lost acknowledgements.
| Form | Pattern | Delivers |
|---|---|---|
| Catch-all | * | Every event. |
| State pattern | *.final | Every event whose name ends in .final. |
| Name prefix | token.transfer.* | Every event whose name starts with token.transfer.. |
| Exact name | token.transfer.final | That initial event. |
Syntax rules
- A segment contains lowercase letters, digits, and hyphens. A hyphen sits between two letters or digits.
- Dots separate segments, and no segment is empty.
*is a complete segment. It stands alone, comes first in a state pattern, or comes last in a name prefix.- A name prefix has one or more segments before
.*. - An exact name has exactly three segments.
The patterns token.*.final and Token.transfer.* break these rules. The platform answers a request that contains such a pattern with status 400 and the error BAD_REQUEST, id DALP-0001.
Validation
A pattern with valid syntax must also pass the registry rules. The platform applies them on POST /api/v2/webhooks, and on PATCH /api/v2/webhooks/{webhookId} when the body supplies subscriptions. A pattern or list that fails answers status 400 with the error WEBHOOK_SUBSCRIPTION_INVALID, id DALP-0534. The error is not retryable. Change the list and send the request again. The Platform API error reference lists both errors.
The state in a state pattern must be one of pending, provisional, final, retracted, or recalled. A name prefix or an exact name must match a registered event. The pattern *.recalled is accepted but delivers nothing today. The reserved name compliance.freeze.recalled is also accepted as an exact subscription, although no action sends it.
| Pattern | Result | Reason |
|---|---|---|
* | Accepted | The catch-all is always valid. |
*.final | Accepted | final is a lifecycle state. |
*.pending | Accepted | pending is a lifecycle state. No live event name ends in .pending, so the pattern delivers nothing today. |
*.confirmed | Rejected | confirmed is not a lifecycle state. |
ledger.entry.* | Rejected | No registered event name starts with ledger.entry.. |
token.transfer.retracted | Rejected | A retraction of a .provisional or .final event cannot be named exactly. Use token.transfer.* or *. |
Retraction subscriptions
A retraction is an event whose name ends in .retracted. It withdraws an earlier event, and the retraction supersedes that event. The platform rejects a list when one of its patterns matches a retraction and no pattern in the list matches the event that the retraction supersedes. The rule applies when the name of the superseded event ends in .pending, .provisional, or .final.
| List | Result | Reason |
|---|---|---|
*.provisional, *.final, *.retracted | Accepted | Every retraction has its source event in the list. |
*.retracted | Rejected | The list contains no source events. |
*.final, *.retracted | Rejected | Retractions of .provisional events, such as the retraction of token.transfer.provisional, have no source. |
*.provisional, *.retracted | Rejected | Retractions of .final events, such as custody.deposit.retracted, have no source. |
token.transfer.* | Accepted | The prefix delivers token.transfer.provisional, token.transfer.final, and token.transfer.retracted. |
token.corporate-action.retracted | Accepted | The event it supersedes, token.corporate-action.announced, has no lifecycle state at the end of its name. |
Worked examples
| Pattern | Delivers |
|---|---|
* | Every event. |
*.final | Every event whose name ends in .final, such as token.transfer.final and asset.burn.final. It skips token.transfer.provisional. |
token.transfer.* | token.transfer.provisional, token.transfer.final, and token.transfer.retracted. |
funding.* | funding.requirement.raised, funding.requirement.resolved, and funding.requirement.expired. |
identity.registration.provisional | Selects that initial event. A reorg can also send identity.registration.retracted after a successful provisional delivery, without a matching retraction pattern. |
Default subscriptions
A new endpoint receives events that match three state patterns: *.provisional, *.final, and *.retracted. The platform applies them when the create request omits subscriptions. The Console create form starts with the same three patterns selected.
State patterns match the last part of the event name. They never read the lifecycle_state field of the envelope. The defaults therefore skip an event whose name ends in a word other than a state, even when its envelope shows provisional or final. funding.requirement.raised shows final and ends in raised. trading-venue.price-alert.triggered shows provisional and ends in triggered. No default pattern matches either name.
An explicit empty list, [], selects no new events. It does not request the defaults. Repeated or overlapping patterns select an endpoint once, rather than creating a copy for each matching pattern. Automatic reorg corrections for provisional events delivered earlier can still arrive.
An existing endpoint keeps its stored list. The defaults apply only at creation. An update that supplies subscriptions replaces the stored list, so adding one pattern means sending the full list. An update that omits subscriptions leaves the list unchanged.
Events the default subscriptions do not deliver
A new endpoint does not receive these events, because the last part of each name matches no default pattern. The name prefix in the second column delivers the event, and it also delivers the other live events that start with it. The exact event name works as well.
| Event | Subscribe with |
|---|---|
custody.deposit.held | custody.deposit.* |
funding.requirement.expired | funding.requirement.* |
funding.requirement.raised | funding.requirement.* |
funding.requirement.resolved | funding.requirement.* |
token.corporate-action.announced | token.corporate-action.* |
token.corporate-action.completed | token.corporate-action.* |
token.corporate-action.paid | token.corporate-action.* |
token.document.published | token.document.* |
trading-venue.announcement.published | trading-venue.announcement.* |
trading-venue.announcement.withdrawn | trading-venue.announcement.* |
trading-venue.price-alert.triggered | trading-venue.price-alert.* |
transaction.request.broadcast | transaction.request.* |
transaction.request.cancelled | transaction.request.* |
transaction.request.confirmed | transaction.request.* |
transaction.request.dead-lettered | transaction.request.* |
transaction.request.failed | transaction.request.* |
Choose patterns for your integration
Each row maps a need to a list that the platform accepts.
| You need | Subscribe with | Behavior |
|---|---|---|
| Every event | * | Delivers every live event, including the events that the defaults skip. |
| The defaults and one skipped family | *.provisional, *.final, *.retracted, funding.requirement.* | An update replaces the stored list, so the request must contain all four patterns. |
| Final events only | *.final | Delivers no retraction, including custody.deposit.retracted, the retraction of a final event. It skips every event whose name does not end in .final, such as identity.registration.provisional. |
| Events and their corrections | *.provisional, *.final, *.retracted | These are the defaults. A list with *.retracted and without the matching source patterns is rejected. |
| One event family | token.transfer.* | Delivers the provisional, final, and retracted events of the family. It passes the retraction rule on its own. |
| One event | identity.registration.provisional | Selects that initial event. Automatic reorg corrections for a previously delivered provisional event can also arrive. |
The Console create and edit forms offer *.pending, *.provisional, *.final, *.retracted, and transaction.request.* as checkboxes. The transaction-request option starts unchecked. Other name prefixes and exact names need the Platform API.
Related
- Event catalogue: every live event, when the platform sends it, and what to do with it.
- Lifecycle states: what each state means and which sequences an endpoint sees.
- Consuming webhooks: identifiers, deduplication, retries, and retractions on the receiving side.
- Receive DALP webhooks: register an endpoint, verify the signature, and rotate the secret.
- Webhook endpoints in the Console: create an endpoint and choose its subscriptions.
Event catalogue
Every webhook event the platform sends today, grouped by domain, with its lifecycle state, its trigger and the action your endpoint takes.
Lifecycle states
The lifecycle states that DALP webhook events send today, the sequences an endpoint receives, and the states the platform reserves.