Overview
An off-ramp converts a stablecoin held by a customer into fiat money delivered to a payout destination (bank/wallet) via a supported rail. You can use floating rates (market-aligned at execution) or locked rates (guaranteed for a short window).Prerequisites
Before initiating an off-ramp transaction:- Verified Customer — Customer must be KYC-approved (see onboarding).
- Payout destination — Bank account details or payment code to send the money to.
- Exchange Rate (optional) — Choose a floating or locked quote.
- Partner Fee (optional) — Configure custom fees (see partner fees).
- Currencies & rails — Use any supported fiat currency as source and any supported stablecoin as target on any supported payment rail (examples below are illustrative only).
Transaction Overview
1
Initiate Off-Ramp
Create the transaction with an amount and currencies (floating rate), or
pass a locked
exchangeRateId
.2
Funds Withdraw
Lumx pulls funds from the customer’s wallet and instantly confirms it —
there is no deposit required.
3
Funds Conversion
Conversion runs at the locked quote or current market rate; the payout
amount is calculated.
4
Fiat Transfer
Funds are settled to the given bank account.
Creating an Off-Ramp Transaction
Option 1: Floating Rate
Use current market rates determined at execution time:Request
Parameter | Type | Required | Description |
---|---|---|---|
customerId | string | Yes | UUID of the verified customer |
sourceCurrency | string | Yes | Asset code (e.g., USDC , USDT , or another supported token) |
sourceAmount | string | Yes | Amount in sourceCurrency |
targetCurrency | string | Yes | Fiat ISO code (e.g., BRL ) |
payment.rail | string | Yes | Payout rail (e.g., PIX ) |
payment.* | mixed | Yes | Rail-specific payout fields (e.g., Pix keyType /keyValue , SEPA IBAN, etc) |
partnerFeeId | string | No | Optional partner fee configuration |
Note: Currencies and rails above are examples only. Your integration
can use other supported currencies/assets/rails without changing the schema.
Option 2: Locked Rate
Use a pre-locked exchange rate for guaranteed conversion:Request
Parameter | Type | Required | Description |
---|---|---|---|
customerId | string | Yes | UUID of the verified customer |
exchangeRateId | string | Yes | ID of the locked exchange rate (use before expiresAt ) |
payment.rail | string | Yes | Payout rail (e.g., PIX ) |
payment.* | mixed | Yes | Rail-specific payout fields (e.g., Pix keyType /keyValue , SEPA IBAN, etc) |
partnerFeeId | string | No | Optional partner fee configuration |
When using
exchangeRateId
, you don’t need to input currencies/amounts;
they’re derived from the locked rate you got earlier. Attempts after expiry
will be rejected.Response
Field | Description | Present when |
---|---|---|
id | Unique transaction identifier | all statuses |
customerId | Customer identifier | all statuses |
state.status | Current status: TRANSFERRING_STABLECOIN → TRADING → TRANSFERRING_FIAT → SUCCESS / FAILED` | all statuses |
request.payment.rail | Payout rail (e.g., pix ) | all statuses |
request.payment.* | Rail-specific payout fields (e.g., Pix keyType /keyValue ) | all statuses |
state.receipt.* | Conversion breakdown after settlement: rate , sourceAmount , targetAmount , currencies, fees | SUCCESS |
state.receipt.fees.lumx.* | Lumx fee components (e.g., rate , flat , currency ) | SUCCESS |
state.receipt.fees.partner.* | Partner fee components (if configured) | SUCCESS |
state.transactionHash | Hash of the on-chain delivery transaction | SUCCESS |
state.blockExplorerUrl | Link to view the on-chain transaction | SUCCESS |
Field availability is status-dependent. For locked quotes, ensure the
transaction is created and funded before the rate’s
expiresAt
;
otherwise, the transaction will be rejected or end up as failed
.Off-ramp states
Field | Description |
---|---|
TRANSFERRING_STABLECOIN | Pulling funds from the source stablecoin. |
TRADING | Trading from stablecoin to fiat |
TRANSFERRING_FIAT | Fiat payout in progress |
SUCCESS | Transaction has been settled and the customer has received the funds |
FAILED | Transaction has failed. |
REFUNDING | transaction has failed and funds will be sent back to the wallet. |
REFUNDED | funds have been successfully sent back. |
Transaction Monitoring
Once we receive the deposit for your transaction, we will move the funds to the destination. You can use the API to check the state of the transaction or listen to webhooks.Next steps
- Learn about Exchange Rates for guaranteed rates
- Configure Partner Fees for custom fee structures
- Explore On-Ramp Transactions to convert fiat to stablecoins