Skip to main content
Three related surfaces sit under /v1/fx:
  • Indicative rate (GET /v1/fx/rate) — read-only, cheap, non-binding. For display.
  • Lockable quote (POST /v1/fx/quote) — binding rate for a short window. Use when you need price certainty before committing.
  • Exchange (POST /v1/fx/exchange) — executes a locked quote, moves funds between your own merchant balances in different currencies.
Plus — cross-currency payouts automatically use FX under the hood when you submit POST /v1/payouts with different source_currency and dest_currency.

When you need each

You want to…Use
Show a customer what a payout will cost them in their currencyGET /v1/fx/rate
Lock in a rate before showing “send” to the customerPOST /v1/fx/quote then POST /v1/fx/exchange
Convert your own balance from one currency to anotherPOST /v1/fx/quote then POST /v1/fx/exchange
Send a payout that debits one of your currencies and credits another on the beneficiary’s sidePOST /v1/payouts with different source/dest currencies — FX is automatic

Indicative rates

For display-only use. Two currencies, optional recipient-side (buy) amount:
Response:
  • mid_market_rate — raw interbank rate
  • customer_rate — mid-market adjusted by your pricing plan’s FX markup (fx_markup_bps)
  • sell_amount — computed using customer_rate from the supplied buy_amount
  • When buy_amount is omitted, the response prices a single unit (buy_amount=1) for rate display
In sandbox, rates are served by the frankfurter.app public data feed. Rate-limited to 30 per minute per IP. The rate is not locked — by the time you execute, it may have moved.

Lockable quotes

When you need certainty:
Supply either sell_amount OR buy_amount — Anton computes the other side at the quoted rate. The response includes an id (fxq_...) and an expires_at. Execute before that moment.
Lockable quotes are rate-limited at 30/min per IP.

Executing an exchange

Exchange is idempotent:
The exchange:
  • Debits sell_amount from your merchant balance in sell_currency.
  • Credits buy_amount to your merchant balance in buy_currency.
  • Records an fx.exchange.* webhook event and an audit entry.
If the quote has expired, you get 410 quote_expired — request a new quote. Rate-limited at 10/min per IP.

FX on cross-currency payouts

You typically don’t call /v1/fx/* explicitly when sending a payout — Anton handles it transparently:
Anton computes the required source_amount using current pricing (rate + markup + fee + buffer), debits your USD balance, converts, and pays the beneficiary in EUR via SEPA. The returned Payout carries FX detail — exchange_rate, fee, fee_currency, buffer_amount, buffer_currency. The buffer_amount is a cross-currency rate buffer held during processing and released on settlement. When to lock separately: if your application needs to show the exact source_amount to the end user before they confirm, pre-lock via POST /v1/fx/quote and surface the quote’s customer_rate. The payout will use the same corridor pricing but isn’t bound to the quote unless you execute against the locked quote explicitly (via the merchant account funding path — typically dashboard-driven).

Listing exchange history

Filters: sell_currency, buy_currency, created_after, created_before. Cursor-paginated. Each exchange has a status (pending / completed / failed) and, if it was created to fund a cross-currency payout, a payout_id.

What can go wrong

Your sell-currency balance can’t cover the exchange. Fund your balance or size the exchange down.
The lock window passed. Request a new quote — the rate may have moved in either direction.
Anton doesn’t currently support FX in the requested pair. See GET /v1/currencies for what’s available.
Upstream provider can’t honor the locked rate. Rare. Retry after a short delay.
Upstream rate feed is down. Honor Retry-After if present and back off.

Subscribe to FX webhooks

  • fx.quote.created
  • fx.exchange.created
  • fx.exchange.completed
  • fx.exchange.failed
See Webhook Events for payload schemas.

Next steps

Send a payout

Including cross-currency payouts that use FX transparently.

Handle webhooks

React to fx.* events on your balance-sheet reconciliation.