Prerequisite: You need a KYC-approved wallet with tokens and an active bank account on your organization.
See Onboarding Customers for the full onboarding flow.
Offramp Flow
Discover Assets
Show Details
Show Details
Either of these endpoints will give you the asset identifiers needed for quotes:
- GET /ramp/assets — Requires auth. Returns only assets available for your specific blockchain, currency, and wallet. Best for building integrations where you already know the customer’s wallet.
- GET /lookup/stablebonds — Public, no auth. Returns all stablebonds across all chains with pricing and supply data. Best for exploring what’s available before onboarding a customer.
identifier from either response as the asset value in your quote.Asset identifier format differs by chain:
- Solana — Base58 mint address (e.g.
AvvetPGuuB5FD5m86fpw3LtDKyQoUFT1mG9WarNQLW4q) - Stellar —
CODE:ISSUERformat (e.g.CETES:GC3CW7...) - EVM (Base, Polygon) — Raw contract address only (e.g.
0xcC77c598d42f2f78Beb42C91d12B9d4041a5cE29)
SYMBOL:0x... on EVM chains will return UnsupportedBlockchain.Create a Quote — POST /ramp/quote
Show Details
Show Details
All orders require a quote. Quotes expire after 2 minutes. For offramps, set
type: "offramp" with the token identifier as sourceAsset and the fiat currency as targetAsset. See POST /ramp/quote for the full schema.Copy
Ask AI
curl -X POST https://api.sand.etherfuse.com/ramp/quote \
-H "Authorization: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "<uuid>", # You generate this UUID
"customerId": "<org_uuid>", # From onboarding
"blockchain": "base",
"quoteAssets": {
"type": "offramp",
"sourceAsset": "0xcC77c598d42f2f78Beb42C91d12B9d4041a5cE29",
"targetAsset": "MXN"
},
"sourceAmount": "50"
}'
Create an Order — POST /ramp/order
Show Details
Show Details
The
quoteId carries the direction, blockchain, and amounts from your quote — no need to repeat them. The response includes orderId and a burnTransaction — a pre-built, unsigned transaction that burns the customer’s tokens. See POST /ramp/order for the full schema.Do not build your own transaction unless using anchor mode. Always use the
burnTransaction provided by Etherfuse — it contains the correct parameters, amounts, and contract calls.Copy
Ask AI
curl -X POST https://api.sand.etherfuse.com/ramp/order \
-H "Authorization: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"orderId": "<uuid>", # You generate this UUID
"bankAccountId": "<bank_account_uuid>", # From onboarding
"cryptoWalletId": "<wallet_uuid>", # From onboarding
"quoteId": "<quote_id_from_step_1>" # From Step 2
}'
The response includes a
statusPage URL — e.g. https://devnet.etherfuse.com/ramp/order/<order_uuid>. Open it in a browser to sign the burn transaction and track progress without building wallet integration into your test harness.Sign the Burn Transaction
Show Details
Show Details
Unlike onramps, offramps require an on-chain action: the customer must sign and submit the burn transaction to release their tokens. You can handle this two ways:
- In your app — Deserialize the
burnTransactionfrom the order response ororder_updatedwebhook, sign it with the customer’s wallet, and broadcast it to the network. - Via the status page — Use the
statusPageURL from the order response (e.g.https://devnet.etherfuse.com/ramp/order/<order_uuid>) to review and sign the transaction in the Etherfuse UI.
Verify Completion — GET /ramp/order/{order_uuid}
Show Details
Show Details
Once the burn is confirmed on-chain, the system detects it and initiates the fiat payout automatically. Status progression:
created → funded (burn confirmed) → completed (fiat sent). See GET /ramp/order for the full response schema.No fiat simulation needed. Unlike onramps, there is no
fiat_received step for offramps. The sandbox processes the fiat payout automatically once the burn transaction is confirmed on-chain.Copy
Ask AI
curl -H "Authorization: <api_key>" \
https://api.sand.etherfuse.com/ramp/order/<order_uuid>
Anchor Mode (Stellar Only)
For Stellar offramps, you can use anchor mode instead of the default burn transaction flow. In anchor mode, you build and submit the payment transaction yourself — Etherfuse provides the destination address and memo. This is useful when you want full control over transaction construction, or when integrating with wallets that support SEP-24-style withdrawal flows.Create Order with useAnchor
Show Details
Show Details
Add The response includes anchor-specific fields instead of a
"useAnchor": true to your order request. The quote must be for a Stellar offramp.Copy
Ask AI
curl -X POST https://api.sand.etherfuse.com/ramp/order \
-H "Authorization: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"orderId": "<uuid>",
"bankAccountId": "<bank_account_uuid>",
"cryptoWalletId": "<wallet_uuid>",
"quoteId": "<quote_id>",
"useAnchor": true
}'
burnTransaction:Copy
Ask AI
{
"offramp": {
"orderId": "...",
"withdrawAnchorAccount": "GABPM7AXX...",
"withdrawMemo": "RkFLRU1FTU8xMjM0NTY3ODkw...",
"withdrawMemoType": "hash"
}
}
Build and Submit Payment
Show Details
Show Details
Build a Stellar payment transaction to the Sign and submit the transaction to the Stellar network.
withdrawAnchorAccount with:- Asset & amount from your quote (e.g., USDC, XLM, or CETES)
- Memo — decode
withdrawMemofrom base64, then attach as aMemo.hash
Copy
Ask AI
const memoBytes = Buffer.from(withdrawMemo, "base64");
const tx = new StellarSdk.TransactionBuilder(sourceAccount, { fee, networkPassphrase })
.addOperation(StellarSdk.Operation.payment({
destination: withdrawAnchorAccount,
asset: sendAsset,
amount: quoteAmount,
}))
.addMemo(StellarSdk.Memo.hash(memoBytes.toString("hex")))
.setTimeout(300)
.build();
Show Chain-specific quote examples
Show Chain-specific quote examples
Solana — Use the Base58 mint address as Stellar — Use Base / Polygon — Use the raw contract address:
sourceAsset:Copy
Ask AI
{
"blockchain": "solana",
"quoteAssets": {
"type": "offramp",
"sourceAsset": "AvvetPGuuB5FD5m86fpw3LtDKyQoUFT1mG9WarNQLW4q",
"targetAsset": "MXN"
}
}
CODE:ISSUER format:Copy
Ask AI
{
"blockchain": "stellar",
"quoteAssets": {
"type": "offramp",
"sourceAsset": "CETES:GC3CW7...",
"targetAsset": "MXN"
}
}
Copy
Ask AI
{
"blockchain": "base",
"quoteAssets": {
"type": "offramp",
"sourceAsset": "0xcC77c598d42f2f78Beb42C91d12B9d4041a5cE29",
"targetAsset": "MXN"
}
}
Show Common errors
Show Common errors
| Error | Cause | Fix |
|---|---|---|
UnsupportedBlockchain | Using SYMBOL:0x... format on an EVM chain | Use the raw contract address only |
Terms and conditions have not been completed | Wallet not KYC-approved | Complete the onboarding flow |
Quote not found or expired | Quote TTL is 2 minutes | Create a fresh quote |
Bank account not found | Bank account not owned by the requesting org | Verify the bank account belongs to your organization |
quote_id is required | Missing quote — the quoteless path is deprecated | Create a quote via POST /ramp/quote first |