SettleMint
ConceptsEvents out

Platform Event

A Platform Event tells an integration what happened through a named, versioned message, so it need not interpret raw chain logs.

One chain fact becomes one row for each subscriber.An indexed chain fact enters at the top, identified by chain, block number and log index. It passes through the catalog, the focal element: a fixed set of named events, one payload shape for each name and version, with machine-readable definitions generated from the registry. From the catalog the fact fans out into one row for each subscribed endpoint. Every row carries its own identifier, unique across the whole platform; its sequence number is scoped to the endpoint, so two endpoints can both hold sequence one for the same fact. Rows commit in the same transaction as the indexed fact, ordered by chain position and then each endpoint's own sequence. At the bottom, a later chain reorganisation never edits a row already sent: a retracted event arrives instead, naming the identifier it replaces.One chain fact becomes one row for each subscriber.The same figure as the desktop variant, drawn portrait for phone widths. An indexed chain fact passes through the catalog, which fixes each event's name and payload shape and supplies the generated machine-readable definitions. Below the catalog, a single stem splits into two equal branches, one per subscribed endpoint, and the branches rejoin below both endpoints into one row per endpoint. Rows commit with the indexed fact, ordered by chain position and then endpoint sequence. A chain reorganisation never edits a row already sent: a retracted event names the identifier it replaces.

The catalog decides what an event is called and what it contains. Everything downstream copies that decision.

An integration reads what happened without polling the chain or re-deriving finality itself: one list binds every event name and version to a payload shape, and registering the same pair twice fails at startup.

Every event names its lifecycle state. Read it with the event type: final can mean chain finality or a committed platform outcome. A final transaction-request event does not itself confirm a token movement.

Delivery retries can produce duplicates. Deduplicate on the event identifier and reconcile missing or retracted events.

Why an integration needs a catalog, not raw logs

A platform event is how an integration learns what happened on the platform: what occurred, when, and how settled that fact is. A chain log answers the first two on its own. It says nothing about the third, because the block behind it can still be reorganised.

The alternative to the platform's event vocabulary is an integration that reads raw logs itself. It decides, on its own, how deep a block must sit before a fact counts as final, and what to do when a block it already trusted gets replaced. Made once, by the platform, that decision is a fact every subscriber can check. Made independently by every integration, it is a second reading of the same chain, taken on that integration's own schedule and its own judgment of depth.

Asset Lifecycle names the general risk in that second reading. Spreading one instrument's issuance, custody, trading and reporting across separate systems turns every boundary between them into a reconciliation, and a reconciliation is where an instrument's ledger state and its legal record drift apart. A platform event holds that boundary at one place: what the integration was told, checked against what the platform's own indexed record says happened, from a name and a payload shape fixed by one registered list.

That list is not tied to one stage of an instrument's life the way a coupon payment belongs to servicing. Issuance, servicing and an eventual retirement each produce their own facts, and each one reaches an integration through this same catalog, tagged with one of five lifecycle states.

Why this catalog lives on the platform, not in a tenant's own indexer

The alternative to a platform-run catalog is a tenant indexer running beside the platform: watching the same chain, choosing its own reorg depth, and turning raw logs into its own vocabulary. That second indexer answers the same question the platform already answers, from a read of the chain that only the tenant sees.

This catalog holds no second reading, because the same indexer that decides a chain fact for the platform's own record is the one that derives the outbox row a subscriber later receives. The event and the indexed fact it describes come from that one decision, not from two.

For a financial institution operating a regulated instrument, two different readings of the same chain fact would leave the integration's own reconciliation and the platform's ledger starting from different guesses instead of the same registered description.

A vocabulary that cannot move under you

A platform event is one entry in a vocabulary defined by a single registry. Each entry binds an event name and version to one payload shape. Registering the same name and version twice fails at startup.

That guarantee targets the two quiet ways an integration built on notifications usually breaks. A field changes shape and the consumer keeps parsing the old one. Or a name starts covering a slightly different occurrence and nobody tells the consumers. Both fail silently, and a reconciliation turns them up weeks later.

The platform generates the machine-readable event manifest, event types for the TypeScript SDK, and sample payloads from that registry. The event catalogue is written by hand and checked against the registry. It explains when each event is sent and what a receiver does with it. Payload schemas and examples stay in the machine-readable definitions. Registration alone does not prove the platform sends an event; the catalogue separates live events from reserved names.

An integration selects the published payload contract by event name and version. Read both fields before interpreting the payload.

The envelope states how settled a fact is

Every platform event has a lifecycle_state: pending, provisional, final, retracted, or recalled. Recalled is reserved; no live event uses it today. Many names end in a state, such as token.transfer.final, but others end in a word such as raised or published. Read the envelope's state and event type together. The lifecycle reference describes the live sequences and reserved states.

Lifecycle vocabulary includes one reserved state.The vocabulary has five states. Recalled is reserved; the platform does not send it today. A pending event reports a transaction request that was broadcast and is not yet confirmed. A provisional chain event reports an observation that a reorganisation may remove. A final chain event follows the configured finality depth. Retractions withdraw earlier facts after a reorganisation or a business reversal. A state change is a separate event, not an edit to a delivery already sent.Lifecycle vocabulary includes one reserved state.The same vocabulary in a portrait layout. Recalled is reserved; the platform does not send it today. A pending event reports a transaction request that was broadcast and is not yet confirmed. Provisional chain observations may be removed by a reorganisation. Final chain events follow the configured finality depth. A retraction withdraws an earlier fact after a reorganisation or a business reversal. A later event never edits a delivery already sent.

A state change is a new event, and so is a correction. Nothing ever edits a delivery already sent.

For chain observations, provisional means included but still within the configured reorg depth, and final means the source block has passed that depth. Current transfer producers emit provisional at inclusion and final after the depth is reached. A reorg may retract a delivered provisional event; it does not retract a final event.

A fact does not change state in place. The same movement reported first as provisional and later as final reaches you as separate events with separate identifiers. Watch for the later event rather than for a field changing on the earlier one.

A retraction reports that an earlier fact no longer stands. It can follow a chain reorganisation or a business reversal, such as a trade bust. The platform leaves the earlier delivery intact. The consumer contract defines how to match the correction, including when its supersedes field is absent or names an event you never received.

Pending reports a transaction request that the platform broadcast and that is not yet confirmed. A request outcome uses final, including a failure or cancellation. This is the request's outcome, not a token movement's chain finality. Recalled is a reserved state. The platform sends no event with that state today. A recall request is refused because no live event has a recalled counterpart.

From one log to one row per subscriber

For an event derived from a chain log, the indexer writes one outbox row for every endpoint whose subscription matches the event name, in the same database transaction as the indexed fact. No queue sits in memory between the two, so the event and the indexed state it describes commit together or not at all.

Transaction-request events describe a different source: a state change recorded inside the platform. The platform records the event together with that state change, rather than deriving it from an indexed chain log.

The fan-out is per subscriber, not per fact. Ten subscribed endpoints mean ten rows from one log, each signed on its own and each with its own identifier, so one endpoint's delivery history says nothing about another's.

Each subject area the indexer writes decides for itself what a failure to write those rows should do, and the areas disagree. Read one path and assume the other, and the difference will surprise you.

Token movement

The outbox write runs in a nested savepoint. When it fails, the platform logs the failure and commits the indexed movement anyway, and you never receive that notification. A notification never holds the ledger hostage. The cost is that your record can lag the chain silently, with no signal on your end that it happened.

Identity and role changes

An outbox failure propagates and blocks the indexed write, so the whole unit retries together. When the retry succeeds, the indexed change and its notification land in that same commit, so a caller never sees one without the other. No gap can open between the indexed fact and its notification. The cost is that a notification problem delays the indexed record too.

Each endpoint has its own delivery sequence. A later eligible event waits while an earlier event remains pending, including during retry backoff. A linked correction waits until its cause was delivered or can no longer be delivered. Events waiting for chain finality do not block later events. A Replay can deliver an older observation after a newer one, so keep the newest state you hold. The ordering contract states the limits.

Writing a consumer that stays correct

Three properties decide whether a consumer stays correct. It subscribes only to the states it intends to handle, deduplicates on the event identifier, and applies a superseding event by looking up the identifier that event names rather than assuming order.

An endpoint subscribes with patterns. A pattern matches a name prefix, as in token.transfer.*, a name suffix, as in *.final, or one exact name. The defaults match names ending in .provisional, .final, and .retracted, not the envelope's lifecycle state. The subscriptions reference lists live events these defaults skip. A pattern for the reserved pending state delivers nothing today. A subscription change replays no earlier events; Replay is a separate request.

Store it and check it before you act. Delivery, the signed HTTPS POST that carries one event to one subscribed endpoint, uses bounded retries: a retry after a lost acknowledgement can repeat a delivery your endpoint already processed. Nothing on the platform side deduplicates for you.

Treat an event as an append-only record rather than as an update. When a later event supersedes an earlier one, it includes a supersedes field naming the identifier it replaces, and the platform never rewrites the original delivery. That field holds one identifier, never a list, so a superseding event always points at exactly one predecessor. A consumer that applies a retraction by looking up the superseded identifier and reversing its effect stays correct through a reorganisation. A consumer that overwrites in place cannot tell the difference between a correction and a fresh occurrence.

The platform publishes machine-readable definitions as a subscription manifest, the DALP events manifest, with a version marker that identifies the inventory it describes. Pin that marker if you generate code from the manifest, so an inventory change is a decision you make rather than one that arrives during a deploy.

Frequently asked questions

Does subscribing to an event name guarantee the platform sends it?

No. The internal corpus retains unavailable event schemas for historical decoding and future producers. The published manifest lists only event names with a composed producer. At present, live names include the access-control role events, asset creation, burn, issuance and pause events, compliance freeze and unfreeze events, identity registration events, the transfer events token.transfer.provisional, token.transfer.final version 2 and token.transfer.retracted version 2, the identity claim events, the provider verdict event, the trading venue order status event, token sale events, identity status, custody events, and the eleven XvP settlement events under xvp.*.final. Compliance recall, settlement retraction, and pre-inclusion pending names have no active producer.

Can a retracted or recalled event itself be retracted later?

No. A chain reorg retraction supersedes a provisional observation only. A retracted or recalled event is not itself retracted by a later chain reorganisation.

Do two endpoints see the same identifier for the same occurrence?

No. An identifier names one endpoint's delivery record, not the occurrence itself, which is why deduplication works per endpoint rather than across endpoints.

  • Asset Lifecycle: The whole working life of a regulated tokenized instrument, from issuance through servicing to redemption. Each stage produces its own platform events, all through this one catalog.
  • Webhook Delivery: The transport that moves an event to your endpoint: the signed request, the retry schedule and the replay rules. The event is the cargo. Delivery is the vehicle.
  • Error Contract: The stable identifier and taxonomy on a failure, which lets a caller decide whether to retry, fix the request or escalate. It answers for a request that failed. An event reports something that happened.
  • Command Surface: The generated tree of platform commands. Like the event manifest and SDK types, it is generated from its defining contract. The hand-written event catalogue explains the events and is checked against their registry.

On this page