Paying Out
The order of calls for sending money from a customer's balance to a bank account or wallet.
This is a common flow. It covers the order to make the calls in, and each step links to the documentation that explains it in more detail.
Before you start
The customer is ACTIVE, holds the endorsement the payout needs, and has enough in available rather than in total. See Endorsements and Balances.
Paying someone other than the customer is a third party, and Alfred derives that rather than taking your word for it. See Core concepts.
The sequence
1. Register the destination.
POST /v1/customers/{customerId}/linked_accounts
Send the country, the currency and the identifiers, and leave the rail alone. Alfred derives supportedRails[] from what you sent, and derives relationship.relationship_type from the registered holder.
A destination whose route is not LIVE is refused here rather than at payout, so registering early is how you find out. See Payout destinations.
2. Wait for linked_account.updated to reach VERIFIED.
A payout to anything else is refused with recipient_not_linked before anything is locked. Handle EXPIRED as well as REJECTED, because a relationship has a validity window and a destination that worked last quarter can stop working with nobody touching it.
3. Quote, but only if you need one.
POST /v1/customers/{customerId}/quotes
You need a quote for a genuine FX pair, which means the funding balance and the destination are different fiat currencies, or the funding balance is a stablecoin and the destination is not USD.
You do not need one for a same-currency payout. An MXNa balance out to MXN over SPEI is a plain transfer with no FX leg. USDC or USDT to USD is a par redemption, where a quote is optional and only locks fees. See Quotes and pricing.
4. Instruct the payout.
POST /v1/customers/{customerId}/payouts/fiat
POST /v1/customers/{customerId}/payouts/stablecoin
You never name the balance to debit. It resolves from the customer and the quote's pair.
The rail resolves in a fixed order: the quote's rail if you passed a quote, then the body's rail, then the destination's rail if it supports only one. Whatever resolves has to be in supportedRails[] or you get rail_mismatch. If the destination supports several and neither the quote nor the body names one, the request fails on rail.
5. Wait for payout.fiat.updated.
Success is transaction_status: COMPLETE with settlement_status: SETTLED. Read both. A payout that is PROCESSING with FUNDS_EXPECTED has left and is in delivery, which is different from a payout sitting on a compliance hold. See Statuses and lifecycle.
The mistake to avoid
Quoting before the money is there. A quote carries an expiresAt of roughly two minutes. A deposit carries no deadline at all. If you quote and then wait for funds, you will re-quote. Get the funds credited, then quote, then execute.
The related version is quoting for a pair that needs no quote. A same-currency payout with a quote attached is not more correct, it is a request that can fail on an expiry it never needed.
When it goes wrong
A payout that failed without the money leaving gets /reprocess. A payout whose leg came back RETURNED gets /correction. A payout you want to stop or pull back gets /refund. See Refunds, corrections and retries.
In sandbox
Registering a destination normally waits on a review you do not control.
POST /v1/test/linked_accounts/{linkedAccountId}/simulate_activation
This moves it straight to VERIFIED, which is the difference between testing a payout in a minute and waiting on someone else's queue. See Testing in sandbox.
Updated 5 days ago

