Currency conversions
Convert cross-currency fiat (and eligible ledger pairs) between accounts owned by the same customer — for example EUR → NGN on that customer’s ledger. This is not a book transfer (same currency) and not a corridor order quote (fiat ↔ crypto ramp).
Prerequisite: Customers quickstart. Banking gate:
products.deposit_account.status=ready. Both accounts must be status=active and owned by {customer_id}.
Auth and environments
Gates
If banking routes are called before
ready, expect 409 with data such as deposit_account_status and reason: banking_profile_incomplete.
Indicative rates vs binding conversion
Use conversion preview for ledger FX insight and confirm. Do not treat corridor indicative rates as the convert price.
Happy path
1
Confirm banking ready
Poll
GET /partner/customers/{customer_id} until deposit_account.status=ready2
List accounts
Resolve source and destination fiat
account_ids via GET …/accounts (different currencies; both owned by this customer)3
Preview
POST …/conversions/preview with to_account_id + amount → preview_token, rate, expires_at4
Confirm promptly
POST …/conversions with preview_token + idempotency_key before expires_at (often a few minutes)5
Re-list balances
GET …/accounts on source and destination to confirm balances moved1. Resolve accounts
Use ids returned by your API key (do not hardcode from this guide).2. Preview
Preview and confirm must use the same sourceaccount_id. The preview_token seals source, destination, amounts, and rate.
preview_token. Confirm before expires_at. If the quote is already stale at preview time, expect 422 with data.code: quote_expired — request a new preview.
Amounts below the rail minimum return 422 (for example
data.min_amount / data.field: amount). Same source and destination account returns 422 on to_account_id.3. Confirm
idempotency_key on retries after network errors (replay returns the same conversion id). Do not reuse a preview token after a successful confirm — request a fresh preview for the next conversion.
Business rules
- Cross-currency only — source and destination currencies must differ; same-currency moves use book transfers.
- Same customer — both accounts belong to
{customer_id}(not anotherpcus_*under the key). - Preview → confirm on the same source
account_id; respectexpires_at(shorter than many other banking previews). - Balance:
available >= amounton the source account. - Partner-neutral JSON: error
message/datado not expose upstream PSP names. Ops may seeupstream_http_statusonly.