Skip to content
Ledgerline Help

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

  1. Quote. Ask for a rate between two currencies and an amount.
  2. Review. Show the result to a user, or check it against your own limits.
  3. 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_amount and 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.