# Exchange (OTC)

> Execute a two-step OTC currency exchange — lock a quote, confirm at the live rate — using Alpha Ladder's MCP API.

Convert between fiat currencies via Alpha Ladder's OTC desk in two steps: lock a quote, then confirm. The server re-prices at confirmation time, so the final settled rate may differ slightly from the quoted rate.

## Before you start

Call `get_module_permissions` and confirm the `otc` module returns `hasPermission: true`. See [Module permissions](/developers/financial-services/concepts#module-permissions).

## The flow

<Steps>

<Step>

**Browse rates** — call `get_exchange_quote` (fromCurrency, toCurrency) to fetch the current indicative exchange rate without locking a quote or checking balance. Use this to browse rates or compute the source amount needed for a given target amount. This call is safe to repeat; it does not reserve any quote ID.

</Step>

<Step>

**Lock a quote** — call `get_otc_quote` (fromCurrency, toCurrency, totalValue) _(Step 1 of 2)_ to lock a quote at a specific amount. Performs a backend balance check and per-currency limit check. Returns `quoteCode`, `exchangeRate`, `finalAmount`, `validityPeriod` (seconds), and `expiry` (ISO-8601 UTC).

<Callout type="info">If `exchangeRate` or `finalAmount` is an empty string (`""`), the downstream pricing service cannot price this pair right now. Tell the user the rate is unavailable and do not proceed to `confirm_otc_trade`. Let the user retry later or pick a different pair.</Callout>

If `success: false`, show the `message` (e.g. insufficient balance, amount out of bounds) and return to currency selection. Do not auto-retry.

Show `exchangeRate` and `finalAmount` to the user on a confirmation screen along with `validityPeriod` as a UX hint to confirm promptly.

</Step>

<Step>

**Confirm the trade** — call `confirm_otc_trade` (quoteCode) _(Step 2 of 2 — destructive; trades at the live rate)_ to submit the trade using the `quoteCode` from the previous step. The server re-fetches a fresh quote and trades at the live rate; the final `exchangeRate` and `finalAmount` returned here are the **actual settled values** and may differ from the quoted values. Always display these as the final rate, not the quote-stage estimate.

<Callout type="warn">**HTTP 410** = quote context expired (5-minute server window elapsed). **HTTP 409** = live rate drifted beyond the system tolerance from the quoted rate. On either error, inform the user and call `get_otc_quote` again — do not auto-retry.</Callout>

</Step>

<Step>

**Inspect the settlement** — call `get_otc_trade_detail` (tradeCode) to inspect the full settlement record: status, trading pair, base/quote quantities, final price, and settlement timestamps.

</Step>

</Steps>

## Ask in chat

> "Convert 1,000 USD to EUR at the best available rate."

The agent will browse the rate with `get_exchange_quote`, lock a quote via `get_otc_quote`, present the `exchangeRate` and `finalAmount` for your confirmation, then call `confirm_otc_trade` and display the settled rate and `tradeCode`.

## What you get back

`confirm_otc_trade` returns:

| Field | Description |
|---|---|
| `tradeCode` | Unique trade reference (e.g. `"OT2026..."`). Use as the user-facing transaction ID. |
| `exchangeRate` | Actual rate at which the trade was executed. Show this as the **final settled rate**. |
| `finalAmount` | Actual amount received in `toCurrency` at the executed rate. |
| `point` | Loyalty/reward points earned (decimal string). |

Use `get_otc_trade_detail` with the `tradeCode` to retrieve full settlement details at any time.

For OTC-specific HTTP error handling and the quote code reference, see [Response Reference](/developers/financial-services/responses).
