Converting a Balance
The order of calls for moving a customer between currencies or assets they already hold.
A conversion moves a customer between two balances they own, and no value leaves Alfred. Where value does leave, the operation is a payout.
Before you start
The customer holds enough in available on the funding side, and holds the endorsement for the asset they are converting into. A local stablecoin needs the endorsement for that specific asset, in a country where it exists. See Endorsements.
The sequence
1. Price the pair.
POST /v1/customers/{customerId}/quotes
Set fromAmount to fix what is debited, or toAmount to fix what lands. Sending both is an error rather than a way to constrain both ends.
chain is required when either side is a stablecoin and must be omitted otherwise. rail is required when either side is fiat and must be omitted otherwise. Supplying a field the pair shape forbids fails with pair_shape_violation. See Quotes and pricing.
2. Execute against that price.
POST /v1/customers/{customerId}/conversions
The body is quoteId and metadata, and that is the whole body. The customer plus the quote's pair fully determine which balance is debited and which is credited, so there is no account to name.
3. Wait for conversion.updated.
Then read the balance and check both sides moved as you expected. See Balances.
The mistake to avoid
Converting before a cross-currency payout. This is the common one and it costs you a transaction.
A cross-currency payout converts natively. The FX runs as an LP_EXECUTION leg inside the payout itself, alongside the rail leg. Running a conversion first and then paying out gives you two transactions, two sets of statuses to track and two things that can fail, for a result the payout would have produced on its own.
Convert when the customer wants to hold the other currency. Pay out directly when the money is leaving. See Paying out.
Quotes expire
A quote lasts roughly two minutes. Execution has to land inside expiresAt or you get quote_expired, and the fix is a new quote rather than a retry. A quote that already funded something gets quote_consumed.
If you are converting funds that have just arrived, wait for deposit.credited first and quote after. See Collecting into a balance.
Reading it back
GET /v1/conversions/{conversionId}
GET /v1/transactions/{transactionId}/legs
The legs read is where reconciliation happens, because the FX and any rail movement are separate legs with their own provider references.
Updated 5 days ago

