# settlement.transfer.retracted

Source: https://docs.settlemint.com/docs/events/settlement-transfer-retracted
Reference for the DALP settlement.transfer.retracted webhook event that invalidates an earlier settlement transfer event after a chain reorg.



`settlement.transfer.retracted` tells a webhook consumer that an earlier settlement transfer event is no longer valid because a chain reorg invalidated the source log.

Use this event to reverse downstream settlement state created from the superseded event. The retraction is an event outcome signal, not a new settlement instruction. Verify the delivery before you apply the retraction. Match `supersedes` to the earlier event, then keep the retraction as the authoritative state.

## Delivery contract [#delivery-contract]

| Field                           | Value                                   |
| ------------------------------- | --------------------------------------- |
| Event type                      | `settlement.transfer.retracted`         |
| Version                         | `1`                                     |
| Lifecycle state                 | `retracted`                             |
| Counter-signed receipt required | `true`                                  |
| SDK type                        | `Webhook.SettlementTransferRetractedV1` |

Related references:

* `idxr_settlement`: the indexed settlement named by `payload.settlementId`.
* `idxr_transfer`: the indexed transfer row for the event named by `supersedes`.

## When to consume this event [#when-to-consume-this-event]

Consume `settlement.transfer.retracted` when your integration records settlement transfer outcomes from DALP webhooks and needs to unwind a previously accepted event after a chain reorg. Typical consumers include settlement ledgers, reconciliation queues, notification systems, and exception dashboards that mirror settlement transfer status outside DALP.

Do not treat the retraction as a replacement transfer. The event says that the earlier event named by `supersedes` is no longer a valid outcome. Keep the original request or business instruction separate from the event outcome state.

Verify the webhook signature, timestamp, and event identifier before processing the payload. Then store `evt_id`, `supersedes`, `payload.settlementId`, `payload.transactionHash`, `payload.reorgBlockNumber`, and `request.idempotency_key` when present. Your consumer can use those fields to connect the retraction to the replaced event and avoid duplicate rollback work on retry.

See [webhook idempotency and on-chain outcome](/docs/events/idempotency-and-on-chain-outcome/) for the broader pattern across final, retracted, and recalled lifecycle events.

## Payload fields [#payload-fields]

| Field              | Type             | Meaning                                                                              |
| ------------------ | ---------------- | ------------------------------------------------------------------------------------ |
| `settlementId`     | String           | Settlement identifier carried forward from the superseded settlement transfer event. |
| `chainId`          | Integer          | EVM chain identifier for the reorged event.                                          |
| `transactionHash`  | 32-byte EVM hash | Transaction hash from the event that was invalidated by the reorg.                   |
| `supersedes`       | Event identifier | Earlier event that this retraction replaces.                                         |
| `reorgBlockNumber` | Integer          | Fork block used to roll back indexed state and emit retractions.                     |

## Payload schema [#payload-schema]

```json
{
  "type": "object",
  "properties": {
    "settlementId": {
      "type": "string"
    },
    "chainId": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "transactionHash": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{64}$"
    },
    "supersedes": {
      "type": "string",
      "pattern": "^evt_[a-zA-Z0-9]+$"
    },
    "reorgBlockNumber": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "settlementId",
    "chainId",
    "transactionHash",
    "supersedes",
    "reorgBlockNumber"
  ],
  "additionalProperties": false
}
```

## TypeScript SDK example [#typescript-sdk-example]

```typescript
import { verifyWebhook, type Webhook } from "@settlemint/dalp-sdk";

const result = verifyWebhook({
  rawBody,
  headers,
  secret: process.env.DALP_WEBHOOK_SECRET!,
});

if (!result.ok) {
  throw new Error(`Webhook verification failed: ${result.code}`);
}

if (result.event.type === "settlement.transfer.retracted") {
  const event: Webhook.Event<"settlement.transfer.retracted"> = result.event;

  await markSettlementTransferRetracted({
    settlementId: event.payload.settlementId,
    supersededEventId: event.supersedes,
    reorgBlockNumber: event.payload.reorgBlockNumber,
    idempotencyKey: event.request?.idempotency_key,
  });
}
```

## curl example [#curl-example]

```bash
curl -X POST https://consumer.example.com/dalp/webhooks \
  -H "content-type: application/json" \
  -H "webhook-id: evt_docs_settlement_transfer_retracted_001" \
  -H "webhook-timestamp: 1778112000" \
  -H "webhook-signature: v1,docs-example-signature" \
  --data '{"evt_id":"evt_docs_settlement_transfer_retracted_001","type":"settlement.transfer.retracted","version":1,"lifecycle_state":"retracted","supersedes":"evt_docs_original_001","request":{"idempotency_key":"idem_01JZP7R5W8M9N0P1Q2R3S4T5"},"related":{"idxr_settlement":"idxr_settlement_example","idxr_transfer":"idxr_transfer_example"},"payload":{"settlementId":"stl_01JZP7R5W8M9N0P1Q2R3S4T5V6","chainId":537001,"transactionHash":"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","supersedes":"evt_finalSettlement001","reorgBlockNumber":18445201}}'
```

## Version history [#version-history]

* Version `1`: Initial registry entry for `settlement.transfer.retracted`.

## Deprecation [#deprecation]

This event type is not deprecated.

## Manifest [#manifest]

The machine-readable AsyncAPI entry is published in the [DALP events manifest](/.well-known/dalp-events.json).
