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:
  1. Verified Customer — Customer must be KYC-approved (see onboarding).
  2. Payout destination — Bank account details or payment code to send the money to.
  3. Exchange Rate (optional) — Choose a floating or locked quote.
  4. Partner Fee (optional) — Configure custom fees (see partner fees).
  5. 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).
Refer to supported currencies, blockchains, and rails.

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
curl --request POST \
  --url https://api.lumx.io/transactions/off-ramp \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "customerId": "123e4567-e89b-12d3-a456-426614174000",
  "sourceCurrency": "USDC",
  "sourceAmount": "10000.00",
  "targetCurrency": "BRL",
  "payment": {
    "rail": "PIX",
    "keyType": "CPF",
    "keyValue": "123.456.789-00"
  },
  "partnerFeeId": "123e4567-e89b-12d3-a456-426614174004"
}'
Parameters
ParameterTypeRequiredDescription
customerIdstringYesUUID of the verified customer
sourceCurrencystringYesAsset code (e.g., USDC, USDT, or another supported token)
sourceAmountstringYesAmount in sourceCurrency
targetCurrencystringYesFiat ISO code (e.g., BRL)
payment.railstringYesPayout rail (e.g., PIX)
payment.*mixedYesRail-specific payout fields (e.g., Pix keyType/keyValue, SEPA IBAN, etc)
partnerFeeIdstringNoOptional 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
curl -X POST https://api.lumx.io/transactions/off-ramp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "exchangeRateId": "123e4567-e89b-12d3-a456-426614174000",
    "payment": {
    "rail": "PIX",
    "keyType": "CPF",
    "keyValue": "123.456.789-00"
  },
  "partnerFeeId": "123e4567-e89b-12d3-a456-426614174004"
}'
Parameters
ParameterTypeRequiredDescription
customerIdstringYesUUID of the verified customer
exchangeRateIdstringYesID of the locked exchange rate (use before expiresAt)
payment.railstringYesPayout rail (e.g., PIX)
payment.*mixedYesRail-specific payout fields (e.g., Pix keyType/keyValue, SEPA IBAN, etc)
partnerFeeIdstringNoOptional 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
{
	"id": "123e4567-e89b-12d3-a456-426614174003",
	"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
	"type": "OFF_RAMP",
	"request": {
		"sourceCurrency": "BRL",
		"sourceAmount": "10000.00",
		"targetCurrency": "BRL",
		"payment": {
			"rail": "PIX",
			"keyType": "CPF",
			"keyValue": "123.456.789-00"
		}
	},
	"state": {
		"status": "TRANSFERRING_STABLECOIN",
		"payment": {
			"rail": "PIX",
			"keyType": "CPF",
			"keyValue": "123.456.789-00"
		}
	},
	"createdAt": "2024-03-20T15:30:00Z",
	"updatedAt": "2024-03-20T15:30:05Z"
}
Other Off-Ramp Statuses
{
	"id": "123e4567-e89b-12d3-a456-426614174003",
	"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
	"type": "OFF_RAMP",
	"request": {
		"sourceCurrency": "BRL",
		"sourceAmount": "10000.00",
		"targetCurrency": "BRL",
		"payment": {
			"rail": "PIX",
			"keyType": "CPF",
			"keyValue": "123.456.789-00"
		}
	},
	"state": {
		"status": "TRADING",
		"payment": {
			"rail": "PIX",
			"keyType": "CPF",
			"keyValue": "123.456.789-00"
		}
	},
	"createdAt": "2024-03-20T15:30:00Z",
	"updatedAt": "2024-03-20T15:30:05Z"
}
Key Response Fields
FieldDescriptionPresent when
idUnique transaction identifierall statuses
customerIdCustomer identifierall statuses
state.statusCurrent status: TRANSFERRING_STABLECOINTRADINGTRANSFERRING_FIATSUCCESS / FAILED`all statuses
request.payment.railPayout 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, feesSUCCESS
state.receipt.fees.lumx.*Lumx fee components (e.g., rate, flat, currency)SUCCESS
state.receipt.fees.partner.*Partner fee components (if configured)SUCCESS
state.transactionHashHash of the on-chain delivery transactionSUCCESS
state.blockExplorerUrlLink to view the on-chain transactionSUCCESS
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

FieldDescription
TRANSFERRING_STABLECOINPulling funds from the source stablecoin.
TRADINGTrading from stablecoin to fiat
TRANSFERRING_FIATFiat payout in progress
SUCCESSTransaction has been settled and the customer has received the funds
FAILEDTransaction has failed.

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