Skip to main content
Webhooks are how your application reacts to what happens at Etherfuse. A transaction settles, a customer passes KYC, a bank account goes active — Etherfuse sends a signed POST to your endpoint the moment it happens, and your app does the corresponding work in your own system: credit a balance, unlock a feature, notify a user, reconcile an order. The key mental model: a webhook is the trigger for a state change in your product. You don’t poll Etherfuse asking “is it done yet?” — you let the event tell you, then act on the status in the payload.
Webhooks vs. polling. Webhooks fire the instant a state changes. Polling the list endpoints is slower (newly created orders take a moment to index) and wasteful (most requests return “no change”). Use webhooks for anything time-sensitive.

What to do on each event

This is the part most integrations care about: when event X arrives, what should your app do? Each flow below maps the lifecycle to the actions you take in your own system.
Subscribe to order_updated.
StatusWhat happenedWhat your app does
createdOrder created; awaiting the customer’s MXN deposit to the depositClabeShow the customer the depositClabe to pay; mark the order pending
fundedMXN deposit received and confirmedOptionally surface “payment received, delivering tokens”
completedTokens delivered to the wallet (confirmedTxSignature has the tx hash)Mark fulfilled, credit the user, send confirmation
failedOrder couldn’t be completedNotify the customer; reconcile
refundedDeposit didn’t match the order amount; MXN returnedReconcile and tell the customer funds were returned
canceledCanceled before fundingClose the order out in your system
Subscribe to order_updated.
StatusWhat happenedWhat your app does
createdburnTransaction is ready for the customer to signPrompt the customer to sign and submit it (or use anchor mode on Stellar)
fundedThe customer’s transaction is confirmed on-chainSurface “selling, sending MXN”
completedMXN sent to the customer’s bank accountMark the payout as sent
finalizedReversal window has passed — funds can no longer be returnedFinalize your accounting for the order
failedCouldn’t be completedNotify the customer; reconcile
Subscribe to swap_updated.
StatusWhat happenedWhat your app does
createdsendTransaction is ready for the customer to signPrompt the customer to sign and submit it
fundedThe source transaction is confirmed on-chainSurface “swap in progress”
completedTarget tokens delivered to the walletUpdate the user’s balances
failedCouldn’t be completedNotify the customer; reconcile
Reading the payload (not the status sequence): sendTransaction is included only while you still owe the source funds — sign and submit it. Once the funds are received it’s dropped from later payloads. On completion you get two hashes: sendTransactionHash (the customer’s send to Etherfuse) and receiveTransactionHash (Etherfuse’s delivery to the wallet). Which intermediate statuses fire varies by chain (some emit a distinct funds_received update, others don’t), so key your logic off the fields present in the payload rather than expecting a particular status to arrive.
Subscribe to kyc_updated, customer_updated, and bank_account_updated.
StatusWhat happenedWhat your app does
kyc_proposedKYC data submitted, awaiting reviewShow “verification pending”
kyc_approved / customer_verifiedThe customer is clearedUnlock their ability to transact
kyc_rejectedKYC rejected (payload includes updateReason)Block transacting; show the reason; prompt resubmission
bank_account_activeBank account verified and usableEnable offramps/payouts to that account
Gating access on these events is the most common compliance pattern: don’t let a customer onramp, offramp, or swap until you’ve received kyc_approved (or customer_verified) for them.

How delivery works

1

Register an endpoint

Call POST /ramp/webhook with your HTTPS URL and the event type. The response includes a signing secret, returned only once — store it securely.
2

Receive the event

When the event fires, Etherfuse sends a POST with the JSON payload to your URL, plus an X-Signature header.
3

Verify the signature

Recompute the HMAC-SHA256 signature with your secret and compare. See Verifying Webhooks for Node and Python code.
4

Respond 2xx, then do the work

Acknowledge with a 2xx immediately, then run your business logic asynchronously. A slow handler triggers unnecessary retries.

Event types

EventFires when
order_updatedAn onramp/offramp order changes status
swap_updatedA swap changes status
quote_updatedA quote’s status changes
customer_updatedA customer’s verification status changes
kyc_updatedA programmatic KYC submission is reviewed
bank_account_updatedA bank account’s verification status changes

Reliability & best practices

  • Retries. Failed deliveries (a non-2xx response or connection error) are retried up to 3 times with 5-second delays. Return a 2xx promptly to avoid them.
  • Acknowledge fast, process async. Hand the payload to a queue and return 2xx right away; don’t block the response on downstream work.
  • Handle events idempotently. The same event can arrive more than once (e.g. a retry after your 2xx was lost). Dedupe on the resource ID plus its status so reprocessing is harmless — this pairs naturally with the client-generated UUIDs you already use for orders.
  • Don’t rely on ordering. Drive your logic off the status in the payload, not the order in which deliveries arrive.
  • Expose a public HTTPS endpoint. For local development, use a tunnel such as ngrok so Etherfuse can reach your handler.

Verifying signatures

Every delivery is signed so you can confirm it’s authentic: X-Signature: sha256={hex}, computed as HMAC-SHA256 over the RFC 8785-canonicalized JSON body using your webhook secret. Full walkthrough with Node/Python code: Verifying Webhooks.

Managing webhooks

If a transaction expires before the customer signs it, fetch a fresh one with POST /ramp/order/{id}/regenerate_tx or POST /ramp/swap/{id}/regenerate_tx.