# Market and settlement events

Source: https://docs.settlemint.com/docs/api-reference/webhooks/market-events
Webhook events for token sales, trading venues and XvP settlements, with each event's lifecycle state, trigger and the action your endpoint takes.

Three products send the events on this page: token sales, which sell a token to investors, trading venues, which match orders and settle trades on chain, and XvP settlements, which exchange assets between parties. For each event, the tables give its lifecycle state, when the platform sends it and what your endpoint does with it. The [event catalogue](https://docs.settlemint.com/docs/api-reference/webhooks/events) lists the events of every other domain and the reserved names. Payload fields, schemas and examples live in the [machine-readable event definitions](https://docs.settlemint.com/.well-known/dalp-events.json) and in the `Webhook` types of `@settlemint/dalp-sdk`.

In a State cell, `beta` is an event-contract maturity label. It is not a value of the envelope's `lifecycle_state` field. New endpoints use `thin` payloads, which omit personal data fields such as `accountAddress`. If your receiver needs an address field, configure `fat` payloads and acknowledge the required fields before the platform records those events: a replay resends the stored payload and cannot restore a field a thin event left out. [Before using payload fields](https://docs.settlemint.com/docs/api-reference/webhooks/events#before-using-payload-fields) describes the change.

## Primary market [#primary-market]

Primary market events report the life of a token sale, and the platform sends each one after the block that holds its chain log reaches chain finality. Every event names the sale in `saleAddress`. An amount is an integer in base units, the smallest unit of its token or currency, so apply the asset's decimals before you show it.

| Event | State | Sent when | What to do |
| --- | --- | --- | --- |
| `primary-market.delivery.final` | `final` | An investor withdraws purchased tokens from a token sale. The sale holds tokens back for a soft cap, the minimum it must sell, or for a vesting schedule, which releases tokens over time. | Mark the investor's tokens as delivered by the amount in the event. If the investor lost a wallet and recovered the identity, the tokens go to the replacement wallet, so match on the investor in the event. |
| `primary-market.proceeds-withdrawn.final` | `final` | A funds manager withdraws a token sale's proceeds in one payment currency to a recipient. A withdrawal of zero sends no event. | Record the amount against the currency and the recipient in the event. A sale that accepts several currencies sends one event for each currency withdrawn. |
| `primary-market.refund.final` | `final` | A token sale pays an investor back in one payment currency. This happens when the sale fails its soft cap and the investor claims a refund, or when the sale pays back a purchase whose tokens cannot be delivered. | Read `reason`: `sale-failed` refunds a contribution to a failed sale, and `undeliverable-purchase` refunds the payment for tokens that could not be delivered. Reduce the investor's recorded contribution in that currency by the amount in the event. |
| `primary-market.sale-activated.final` | `final` | A sale administrator opens a token sale for subscriptions, in its presale round if one is configured and in its public round otherwise. Resuming a paused sale sends no event. | Open subscriptions in your own systems. `phase` says which round the sale started in: `presale`, which admits whitelisted investors only, or `public-sale`. |
| `primary-market.sale-closed.final` | `final` | A sale administrator ends a token sale, before or after its end time or before it opened, so it takes no more subscriptions. A sale that reaches its end time without being ended sends no closed event. | Stop offering subscriptions in your systems. Expect the outcome in `primary-market.sale-finalized.final`, and do not require an earlier `primary-market.sale-activated.final`. |
| `primary-market.sale-extended.final` | `final` | A sale administrator moves the end time of an active or paused token sale to a later time. | Replace the end time you stored for the sale with `saleEndTime` from the event. |
| `primary-market.sale-finalized.final` | `final` | A token sale that is closed or past its end time is finalised. `outcome` is `succeeded` when the sale met its soft cap or has none, and `failed` otherwise. | After `succeeded`, investors can withdraw held tokens and the sale's proceeds can be withdrawn. After `failed`, investors can claim refunds. |
| `primary-market.subscription.final` | `final` | An investor pays into a token sale with one payment currency to purchase tokens. | Record the purchase with the token and payment amounts in the event. Tokens arrive later with `primary-market.delivery.final` only when the sale holds them for a soft cap or vesting, because a sale with neither delivers at purchase. |

## Trading venue [#trading-venue]

A [trading venue](https://docs.settlemint.com/docs/concepts/issuing-and-markets/trading-venue) matches orders off chain, settles each trade on chain, and delivers the assets when the instrument's holding period, the delay between settlement and delivery, ends. A bust is an approved reversal of a trade. A `provisional` event reports matched activity that has not settled, and the chain events `trading-venue.trade.final` and `trading-venue.trade.retracted` have the state `final` because the platform sends them after chain finality. `trading-venue.trade-settled.final` and `trading-venue.trade-fee.final` go out when the settlement transaction confirms, without waiting for chain finality, and only a bust retracts them.

| Event | State | Sent when | What to do |
| --- | --- | --- | --- |
| `trading-venue.announcement.published` | `final beta` | A venue operator publishes an announcement, for the whole venue or for one instrument. A scheduled announcement sends this event when it goes live at its display-from time, within about 15 seconds, not when it is scheduled. An issuer notice, which a holder of the token's Governance or Supply management role submits through the API, sends this event once a venue operator approves it and the notice goes live. | Use the title, category and severity in the event to alert your users. The event has no body: read it from the announcements endpoint of the Platform API, which applies the caller's audience. |
| `trading-venue.announcement.updated` | `final beta` | A venue operator edits a published announcement's title, body, severity or display end. Saving an edit that changes nothing sends no event. | Refresh the title, category and severity you show, and read the new body from the announcements endpoint of the Platform API. |
| `trading-venue.announcement.withdrawn` | `final beta` | A venue operator withdraws a published announcement. Withdrawing a scheduled announcement before its display-from time sends no event. One withdrawn after that time sends the published event first. | Stop showing the announcement. The announcements endpoint of the Platform API no longer returns it to callers other than operators. |
| `trading-venue.cancellation-batch.completed` | `final beta` | An operator action cancels open orders in one batch: an instrument is delisted or suspended, a participant's orders are cancelled or the participant is blocked, a wallet is removed from a private instrument, or an approved mass cancel runs. A batch that cancelled no order sends nothing. An action that fails partway records its batch but sends no event. | Tell the affected participants and keep the batch id. Read or download the cancelled orders from the cancellation batches endpoint of the Platform API. |
| `trading-venue.market-status.changed` | `final beta` | An operator changes an instrument's lifecycle status. The payload carries the new status and the operator's required reason. | Update the instrument status and retain the reason with the transition. |
| `trading-venue.order-status.provisional` | `provisional beta` | The venue matching engine changes an order: the order is placed or replaced, filled, or changes status in another way. The platform sends one event for each order the change touches. | Update your copy of the order and keep the event with the highest `sequence` for each order. A `filled` status is not a settled trade: wait for `trading-venue.trade-settled.final`. |
| `trading-venue.price-alert.triggered` | `provisional beta` | The price of a matched trade crosses a user's price alert on an instrument. An alert with direction `above` fires at or over its threshold, an alert with direction `below` fires at or under it, and each alert fires once. | Notify the user who set the alert. The price comes from a matched trade that has not settled, so match `tradeId` against `trading-venue.trade-settled.final` before you treat the price as settled. |
| `trading-venue.settlement-fill.aged` | `final beta` | A parked settlement fill stays parked past the age alert threshold, one hour by default. The platform sends one event for each parked interval, with the fill's current age and the threshold in seconds. | Ask a venue operator to open the fill in the Held fills tab and retry it or bust the trade. |
| `trading-venue.settlement-fill.parked` | `final beta` | The venue parks a settlement fill because it could not settle it. The payload carries the refusal reason and the number of settlement attempts started so far. | Read the reason. Retry the fill from the Held fills tab once the cause is fixed, or bust the trade. |
| `trading-venue.trade-fee.final` | `final beta` | The venue charges one side of a settled trade a fee, and the platform records it with the settlement. The platform sends one event for each charged side, together with `trading-venue.trade-settled.final`. | Book the fee against the payer in the event. `amount` is the fee without VAT and `vatAmount` is the VAT on it, zero where none applies. Both are in the base units of the instrument's quote token, the token that prices its trades. `orderRecipientAddress` is the order's asset destination, not the account that receives the fee. |
| `trading-venue.trade-fee.retracted` | `retracted beta` | A bust reverses a settled trade that charged fees. The platform sends one event for each fee the trade charged, together with `trading-venue.trade-settled.retracted`. | Reverse the fee you booked from `trading-venue.trade-fee.final`. `supersedes` is optional and names that event when the platform queued it for your endpoint, so match the fee by `feeId` if it is absent or you never received that event. |
| `trading-venue.trade-leg.parked` | `final beta` | A delivered trade had one leg its receiver could not take. The venue booked that leg to the receiver's free balance in the venue escrow instead of undoing the trade. The platform sends one event for each parked leg, after the `trading-venue.trade.final` event of the same delivery. `leg` is `base`, `quote` or `fee`, and `amount` is in base units of `tokenAddress`. | Keep the trade as delivered and record that the leg waits in the receiver's escrow balance. The receiver withdraws it through the escrow, which runs the token's compliance again, so an unverified receiver cannot take it out until it is verified. Match the trade by `venueTradeId`. |
| `trading-venue.trade-settled.final` | `final beta` | A matched trade settles on chain and the platform records it. The platform sends one event for each trade after the settlement transaction is confirmed and its logs show the fill. | Book the trade as settled. `quoteAmount` is the cash leg, in base units of `quoteTokenAddress`. `delivery` is `delivered` when the assets already moved and `pending-delivery` while the instrument's holding period still applies. |
| `trading-venue.trade-settled.retracted` | `retracted beta` | A bust reverses a settled trade, and the reversal is complete on chain. The platform sends nothing while a reversal transfer is queued, has reverted, or has not completed. | Reverse the settlement you booked from `trading-venue.trade-settled.final`. `supersedes` is optional and names that event when the platform queued it for your endpoint, so match the trade by `tradeId` if it is absent or you never received that event. |
| `trading-venue.trade.final` | `final beta` | The venue contract delivers a trade on chain: its holding period ends and the assets move. A leg the receiver cannot take is booked to the receiver's escrow balance instead, and the trade still counts as delivered. | Treat the trade as delivered. An instrument with no holding period delivers inside the settlement transaction and sends no `trading-venue.trade.final`, so read `delivery` on `trading-venue.trade-settled.final` for those instruments. |
| `trading-venue.trade.retracted` | `final beta` | The venue contract undoes a trade because of a bust while the delivery of the trade is still pending. An undo for any other reason, including an outside cause that blocks delivery, sends nothing. | Mark the trade as undone. Its delivery was still pending, so the platform never sent `trading-venue.trade.final` for it, and the event has no `supersedes`: match the trade by `venueTradeId`. |

The `status` of a `trading-venue.order-status.provisional` event is the engine status the order holds after the change: `pending_reservation`, `armed`, `working`, `partially_filled` or `suspended` while the order can still execute, and `filled`, `cancelled`, `expired`, `rejected` or `pruned` once it cannot. `closeReason` carries the engine's reason for a closed order.

To reconcile these events with the venue's [FIX drop copy](https://docs.settlemint.com/docs/concepts/issuing-and-markets/venue-controls#what-each-drop-copy-report-carries), match them on the identifiers both feeds carry. The `sequence` of a `trading-venue.order-status.provisional` event is the log sequence in the `ExecID`, tag 17, of the drop-copy reports for the same entry. That `ExecID` has the form `<marketId>:<sequence>:<n>`. The event's `occurredAt` equals the reports' `TransactTime`, tag 60. For `trading-venue.trade-settled.final`, `tradeId` equals the `TrdMatchID`, tag 880, of the two fill reports, and `executedAt` equals their `TransactTime`.

## XvP settlement [#xvp-settlement]

XvP stands for exchange-versus-payment. An [XvP settlement](https://docs.settlemint.com/docs/concepts/settlement/xvp-settlement) is a contract that exchanges assets between parties in transfers called legs. Each sending participant approves it and locks its assets in the contract, which is called escrow. A settlement with a leg on another chain also has a hashlock, a hash that blocks execution until its secret is revealed. Every event includes `settlementAddress`. The platform sends it once the block reaches chain finality, and only to endpoints on the System that owns the settlement's factory. A System is an organisation's on-chain DALP deployment.

| Event | State | Sent when | What to do |
| --- | --- | --- | --- |
| `xvp.approval-revoked.final` | `final` | A settlement participant withdraws its approval while the settlement is open. The contract returns any escrow that participant locked in the same transaction, so refund events can come from it. | Store the new `approvedCount` and `requiredCount`, and mark `accountAddress` as not approved. Take the escrow change from `xvp.assets-refunded.final` or `xvp.refund-deferred.final`, because this event has no amount. |
| `xvp.assets-locked.final` | `final` | A settlement participant locks an asset in the settlement's escrow while approving it. The platform sends one event for each asset that the approval adds escrow for. | Add `amount` to the escrow you track for `accountAddress` and `assetAddress`. `amount` is the extra escrow this approval adds to what the participant already locked. |
| `xvp.assets-refunded.final` | `final` | Escrow that a participant locked leaves the settlement for that participant. This follows a revoked approval, a cancellation, a withdrawal after the settlement expires, or a `claimRefund` call. | Subtract `amount` from the escrow you track for `accountAddress` and `assetAddress`. After a `claimRefund` call the participant can send the tokens to another address, and the event does not identify that address. |
| `xvp.delivery-claimed.final` | `final` | A recipient calls `claimSettled` to pull a delivery that `xvp.delivery-deferred.final` parked in the settlement. The asset leaves the settlement at this point. | Mark the parked delivery for `accountAddress` and `assetAddress` as delivered. The recipient can choose another receiving address, and the event does not identify it. |
| `xvp.delivery-deferred.final` | `final` | A settlement executes but the transfer to a recipient fails, for example because the token blocks that recipient, so the contract parks the amount in the settlement. Only a settlement with a leg on another chain parks a delivery this way, and only after its secret is revealed. | Do not book the asset as delivered to `accountAddress`. It stays in the settlement until the recipient calls `claimSettled`, which produces `xvp.delivery-claimed.final`. |
| `xvp.refund-deferred.final` | `final` | The contract cannot transfer a participant's escrow back, for example because the token blocks that participant, so it parks the amount in the settlement. The revoked approval, cancellation or withdrawal after expiry that triggered the refund still completes. | Keep the amount in escrow for `accountAddress` and `assetAddress`. It leaves only when the participant calls `claimRefund`, which produces `xvp.assets-refunded.final`. |
| `xvp.settlement-approved.final` | `final` | A settlement participant approves the settlement. The event includes the approval count after the change. | Compare `approvedCount` with `requiredCount`: when they are equal, every approval is in. A settlement with `autoExecute` set then executes in the same transaction, unless it has a leg on another chain whose secret is not revealed. |
| `xvp.settlement-cancelled.final` | `final` | A settlement is cancelled before it executes. A fully approved settlement with a leg on another chain cancels only after every participant that sends an asset on this chain votes to cancel, and the votes alone send no event. | Mark the settlement as cancelled. `cancellerAddress` identifies the caller that completed the cancellation, and `xvp.assets-refunded.final` or `xvp.refund-deferred.final` events from the same transaction return the escrow. |
| `xvp.settlement-created.final` | `final` | A settlement factory creates a settlement and fixes its legs and its cutoff, the time after which the settlement expires. The event includes the hashlock and never the secret that opens it. | Store the settlement by `settlementAddress` and its legs by `legIndex`. `xvp.settlement-executed.final` uses the same leg indexes. |
| `xvp.settlement-executed.final` | `final` | A settlement executes: the contract uses the paying parties' escrow and transfers the assets to the receiving parties. This happens when a caller runs `execute`, or with the last approval when `autoExecute` is set. | Mark the settlement as executed and match `flows` to your stored legs by `legIndex`. A recipient the contract could not pay appears in `xvp.delivery-deferred.final` from the same transaction, and stays parked until `xvp.delivery-claimed.final`. |
| `xvp.settlement-expired.final` | `final` | A caller withdraws the escrow of a settlement that passed its cutoff without executing. Reaching the cutoff alone sends nothing. | Mark the settlement as expired. `callerAddress` identifies the account that withdrew the escrow, and `xvp.assets-refunded.final` or `xvp.refund-deferred.final` events from the same transaction return it. |

## Related [#related]

- [Event catalogue](https://docs.settlemint.com/docs/api-reference/webhooks/events): the events of every other domain, and the reserved names.
- [Subscriptions](https://docs.settlemint.com/docs/api-reference/webhooks/subscriptions): the patterns that select events, and the events the default subscriptions skip.
- [Lifecycle states](https://docs.settlemint.com/docs/api-reference/webhooks/lifecycle): what each state means, with worked sequences.
- [Consuming webhooks](https://docs.settlemint.com/docs/api-reference/webhooks/consuming): identifiers, deduplication, ordering, retries and retractions.
