Appearance
Webhooks
RFQs emit terminal events over the same webhook pipeline as v1: same registration endpoints, same signing secret, same Textile-Signature header, same retry behaviour. Register once and subscribe to whichever events you want.
Registration, signature verification and retries are documented in v1 webhooks and work identically — this page only covers what the RFQ events look like.
Events
| Event | Fires when |
|---|---|
rfq.filled | The swap settled on chain. |
rfq.failed | The signed order's deadline passed and the reported transaction never landed (failReason: "not_landed"). |
rfq.expired | The firm quote lapsed without being executed. |
Register them like any other event type:
json
POST /v1/webhooks
{
"url": "https://your-app.com/webhooks/textile",
"eventTypes": ["rfq.filled", "rfq.failed", "rfq.expired"]
}The event
json
{
"id": "rfq.filled:rfq_…",
"type": "rfq.filled",
"created": "2026-08-07T12:00:09.000Z",
"data": {
"apiVersion": 2,
"rfq": {
"id": "rfq_…",
"chainId": 56,
"sellToken": "0xCNGN",
"buyToken": "0xUSDT",
"sellAmount": "999900010",
"buyAmount": "612000000",
"feeAmount": "99990",
"taker": "0xYourWallet",
"txHash": "0xabc…",
"filledAt": "2026-08-07T12:00:09.000Z",
"failReason": null
}
}
}Two things worth pointing at:
apiVersion: 2is on every RFQ event. v1 events don't carry it. If one handler serves both, branch on this rather than on the event name prefix.- The amounts are what settled, not what you asked for:
sellAmountis the actual debit including the fee,buyAmountis what was delivered, andfeeAmountis the fee that turned one into the other. On an exact-input RFQ the debit is often less than the cap you requested.
Ordering and corrections
Delivery is at-least-once and events are deduped on Textile-Event-Id, same as v1 — so dedupe on it.
The correction case is specific to RFQ and worth handling: a fill that indexes late can arrive after an rfq.failed or rfq.expired for the same RFQ, for up to 24 hours. When that happens rfq.filled is the authoritative outcome and supersedes the earlier event.
Don't treat the first terminal event as final if you also hold a transaction you know was broadcast. A safe handler:
- keys on
rfq.id, - lets
rfq.filledoverwrite an earlierfailed/expired, - never lets
failed/expiredoverwrite afilled.
Not having webhooks
If you'd rather poll, GET /v2/rfq/{id} reports the same states and the same settled amounts. Webhooks are just cheaper.