Before you start
- An approved customer. Request
MXNin theaccountsarray when you create the customer, as described in Coverage. - A USDT balance in the customer’s wallet on a supported network. Fund it with an on-ramp, or send USDT to the wallet address from any external wallet.
1. Create a SPEI destination
A destination is where the pesos land. Send aPOST request to /destinations with rail set to SPEI and currency set to MXN.
Request
Response (excerpt)
Request fields
For a
SELF destination, the holder’s type and tax ID also have to match the customer’s, or the request fails with HOLDER_TYPE_MISMATCH or HOLDER_TAX_ID_MISMATCH.2. Wait for the destination to be approved
It starts withholder.verification.status set to UNDER_VERIFICATION. A payout needs an approved destination, so wait for the destinations.approved webhook before you send funds. A destination that fails verification triggers destinations.final_rejection.
You can also read the destination with GET /destinations/{id} and check holder.verification.status.
3. Check the balance and the limits
Read the customer with the balance and limit options on:Request
INSUFFICIENT_BALANCE. The offramp entry of transactionLimits shows what is left, in the USD equivalent, against the single, daily, and monthly limits. The minimum per payout is the equivalent of USD 40 today, and it may change. See Transaction limits.
4. Quote the conversion
- Floating. Skip the quote and let the off-ramp convert at the rate at execution time. Request a
FLOATINGrate to show an estimate in your UI. - Locked. Request a
LOCKEDrate and pass itsidto the off-ramp asexchangeRateId. The timelock is30s,1m, or5m, and the default is30s. See Exchange rates.
Request
Response (excerpt, illustrative numbers)
finalTargetAmount is what the recipient receives. It is already net of Lumx fees and any partner fee you attach. The difference between the base and final amounts is the fee, not a hidden spread. Lumx does not deduct anything further from the pesos that arrive. Only the recipient’s bank can.
If the lock expires before you use it, request a new one.
5. Create the off-ramp
Send aPOST request to /transactions/off-ramp. The destination fixes the rail and the currency, so you only say where the money goes and why.
Locked rate
Response (202)
Send a new
Idempotency-Key for each payout. If a request times out, retry with the same key and Lumx returns the original result instead of paying twice. See Idempotency.
6. Track it with webhooks
An off-ramp moves throughTRANSFERRING_STABLECOIN, TRADING, TRANSFERRING_FIAT, and then SUCCESS. Each step sends a webhook:
Verify the signature on every request and use the
webhook-id header to deduplicate retries. See Webhooks. To check a transaction without waiting for an event, call GET /transactions/{id}.
Hours and timing
SPEI has no cut-off and runs 24/7/365 with instant settlement. If a bank holiday ever stops SPEI settlement, the payout waits inTRANSFERRING_FIAT and settles as soon as the rail is back. These are processing targets, not guarantees. A transaction held for review (see Request for Information), a large amount that needs extra risk review, or a hold at the recipient’s bank can add time. Lumx counts the off-ramp as complete once the funds leave its banking partner. The SPEI row also lists the Banxico calendar of banking holidays. See Payment rail cut-off times and build your UI around webhook events, not the clock.
Errors
Match oncode, never on message. See Errors.
Related resources
Destinations
Holder relationships and what each one means.
Payment rail cut-off times
Settlement windows for each rail.