FX quotes and conversions
Updated 11 September 20263 min read
On this page
To move value between currencies you request a quote, then book a conversion against it. The quote fixes the rate for a short time so you know exactly what you will get before you commit.
The flow
- Quote. Ask for a rate between two currencies and an amount.
- Review. Show the result to a user, or check it against your own limits.
- Convert. Book the conversion using the quote id before the quote expires.
Request a quote
curl https://api.ledgerline.dev/v1/fx/quotes \
-H "Authorization: Bearer $LEDGERLINE_API_KEY" \
-d sell_currency=USD \
-d buy_currency=EUR \
-d sell_amount=1000000
{
"id": "qte_01JA8M5D2X",
"sell_currency": "USD",
"buy_currency": "EUR",
"sell_amount": 1000000,
"buy_amount": 913400,
"rate": "0.9134",
"mid_market_rate": "0.9189",
"spread_bps": 40,
"expires_at": "2026-09-11T09:15:30Z"
}
Provide either sell_amount or buy_amount, not both. The rate already includes Ledgerline's spread, and mid_market_rate is shown so the cost is visible.
Important
A quote is valid for 30 seconds. The rate is locked for that period. After expires_at, booking against it fails with quote_expired, and you request a new one.
Spread
You pay a spread over the mid-market rate. It depends on your plan.
| Plan | Spread over mid-market |
|---|---|
| Starter | 0.60% |
| Growth | 0.40% |
| Scale | From 0.25%, negotiated by volume |
The spread is the only FX charge. There is no separate conversion fee. See Plans and pricing.
Book the conversion
curl https://api.ledgerline.dev/v1/fx/conversions \
-H "Authorization: Bearer $LEDGERLINE_API_KEY" \
-H "Idempotency-Key: 2d9f5c3a-81b4-4e67-a0c9-5e7b1d4a8f36" \
-d quote_id=qte_01JA8M5D2X \
-d source_account_id=acc_01J9QK5M2A \
-d destination_account_id=acc_01JA8L2R9Q
The source account must hold the sell currency and the destination account the buy currency. Ledgerline books two balanced legs through the FX clearing account, as described in Multi-currency ledgers, and emits an fx.conversion.completed event. A conversion is instant and cannot be canceled, only reversed with a new conversion at a new rate.
Conversions need the transfers:write scope.
Market hours
Foreign exchange markets are closed at the weekend. From Friday 22:00 UTC until Sunday 22:00 UTC, quote requests fail with HTTP 422 and the code fx_market_closed. Outside that window quotes are available around the clock and rates refresh every second.
Plan around this if you convert on a schedule. A payroll run that converts on a Saturday will fail. Convert on Friday before 22:00 UTC, or wait until Sunday night.
Errors
| Code | Cause | Fix |
|---|---|---|
fx_market_closed |
Weekend market closure | Retry after Sunday 22:00 UTC. |
quote_expired |
The quote is older than 30 seconds | Request a new quote. |
currency_mismatch |
An account's currency does not match the quote | Use accounts in the quoted currencies. |
insufficient_funds |
The source account's available balance is too low | Fund the account or lower the amount. |
limit_exceeded |
The conversion is above your plan's limit | See Limits and quotas. |
Practical tips
- Show the user
buy_amountand a countdown, and book immediately on confirmation. - Do not cache quotes. Each is single-use.
- Reconcile conversions through statements, which list the rate and quote id for every conversion.
- Quote and conversion calls count against the standard rate limit.
Indicative rates
Without committing, you can read an indicative rate with GET /v1/fx/rates?sell_currency=USD&buy_currency=EUR. It returns the mid-market rate and the spread for your plan, but it is not locked and cannot be booked.