> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs-v3.openfx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Cheat sheet

> Every v3 endpoint at a glance. Method, path, auth, idempotency, pagination, response shape.

A single-page reference for everything callable in v3. For the narrative version of any row, follow the link.

## Endpoints

| Method | Path                                                                                        | Description                                           | Auth scope | Idempotency-Key | Paginated | Returns                                   |
| ------ | ------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ---------- | --------------- | --------- | ----------------------------------------- |
| `GET`  | [`/v3/fx/pairs`](/v3/api-reference/trade/list-currency-pairs)                               | List tradable currency pairs                          | `view`     | —               | Bounded   | `{data: {pairs: Pair[]}}`                 |
| `POST` | [`/v3/fx/quotes`](/v3/api-reference/trade/create-quote)                                     | Lock a rate (`quoteForSeconds`: 3, 15, 30, 45, or 60) | `trade`    | Required        | —         | `{data: Quote, metadata}`                 |
| `GET`  | [`/v3/fx/quotes/{id}`](/v3/api-reference/trade/get-quote-by-id)                             | Retrieve one quote (pre-trade verification)           | `view`     | —               | —         | `{data: Quote}`                           |
| `POST` | [`/v3/fx/trades`](/v3/api-reference/trade/execute-trade)                                    | Execute a quote                                       | `trade`    | Required        | —         | `{data: Trade, metadata}`                 |
| `GET`  | [`/v3/fx/trades/{id}`](/v3/api-reference/trade/get-trade)                                   | Retrieve one trade                                    | `view`     | —               | —         | `{data: Trade}`                           |
| `GET`  | [`/v3/fx/trades`](/v3/api-reference/trade/list-trades)                                      | List trades, newest-first                             | `view`     | —               | ✓ cursor  | `{data: Trade[], pagination}`             |
| `GET`  | [`/v3/fx/balances`](/v3/api-reference/trade-settlement/list-balances)                       | Per-currency balance                                  | `view`     | —               | Bounded   | `{data: Balance[]}`                       |
| `GET`  | [`/v3/fx/deposits`](/v3/api-reference/trade-settlement/list-deposits)                       | List deposits, newest-first                           | `view`     | —               | ✓ cursor  | `{data: Deposit[], pagination}`           |
| `GET`  | [`/v3/fx/deposits/{id}`](/v3/api-reference/trade-settlement/get-deposit)                    | Retrieve one deposit                                  | `view`     | —               | —         | `{data: Deposit}`                         |
| `POST` | [`/v3/fx/withdrawals`](/v3/api-reference/trade-settlement/create-withdrawal)                | Submit a withdrawal (fiat or stablecoin)              | `trade`    | Required        | —         | `{data: Withdrawal, metadata}`            |
| `GET`  | [`/v3/fx/withdrawals/{id}`](/v3/api-reference/trade-settlement/get-withdrawal)              | Retrieve one withdrawal                               | `view`     | —               | —         | `{data: Withdrawal}`                      |
| `GET`  | [`/v3/fx/withdrawals`](/v3/api-reference/trade-settlement/list-withdrawals)                 | List withdrawals, newest-first                        | `view`     | —               | ✓ cursor  | `{data: Withdrawal[], pagination}`        |
| `GET`  | [`/v3/fx/withdrawal-accounts`](/v3/api-reference/trade-settlement/list-withdrawal-accounts) | List verified withdrawal accounts                     | `view`     | —               | ✓ cursor  | `{data: WithdrawalAccount[], pagination}` |

## Request headers

| Header                | When          | Value                                                                                                                                                                              |
| --------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Authorization`       | Always        | `Bearer <jwt>` — ES256, 60s TTL, single-use (server-enforced nonce uniqueness)                                                                                                     |
| `X-Request-Signature` | Always        | ES256 (IEEE P-1363 base64url) over `METHOD\nCANONICAL_PATH\nCANONICAL_QUERY\nNONCE\nSHA256_HEX(body)`. See [Authentication → Request signing](/v3/authentication#request-signing). |
| `Idempotency-Key`     | Writes (POST) | Client-generated. Pattern `^[a-zA-Z0-9_-]{1,255}$` (UUID v4 recommended)                                                                                                           |
| `Content-Type`        | Writes (POST) | `application/json`                                                                                                                                                                 |

## Response headers

Always set, every response (success and error):

| Header                | Meaning                                                     |
| --------------------- | ----------------------------------------------------------- |
| `X-Trace-Id`          | Per-request ID. Echo back in support tickets.               |
| `X-Request-Timestamp` | Server time the request reached the API (RFC 3339, ms)      |
| `RateLimit-Limit`     | Max requests in current window                              |
| `RateLimit-Reset`     | Seconds until window resets (a duration, not an epoch time) |

Sometimes set:

| Header                                     | When                                                                                        |
| ------------------------------------------ | ------------------------------------------------------------------------------------------- |
| `Idempotency-Replayed`                     | `true`/`false` on every POST — whether the response was replayed from the idempotency cache |
| `Retry-After`                              | Seconds to wait. On `429 RATE_LIMIT_EXCEEDED` and `409 IDEMPOTENCY_IN_FLIGHT` only          |
| `Sunset` + `Link: rel="successor-version"` | On 410 (v1 endpoints after Dec 31 2026)                                                     |

## Resource IDs

All resource IDs are **readable, typed-prefix** strings — a lowercase 3-to-5-letter resource-type prefix plus a Base58 encoding of the underlying UUID. Bare UUIDs never appear in a v3 response body. Server-generated, permanent, safe to store and index.

* Example: `tde_5W7guYdHT24JFnRQrZN9y8`
* Regex: `^[a-z]{3,5}_[1-9A-HJ-NP-Za-km-z]{1,22}$`

See [Resource IDs](/v3/resource-ids) for the prefix table, foreign-key surface, and stability contract.

## Status enums

| Resource            | Values                                                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `Trade.status`      | <Badge color="yellow">PENDING</Badge> · <Badge color="green">EXECUTED</Badge> · <Badge color="red">FAILED</Badge> |
| `Deposit.status`    | <Badge color="yellow">PENDING</Badge> · <Badge color="green">COMPLETED</Badge> · `ERROR`                          |
| `Withdrawal.status` | An unconstrained string reflecting the current lifecycle state (e.g. `COMPLETED`); no closed enum is documented.  |

Trades terminate at `EXECUTED` (atomic single-hop). Deposits terminate at `COMPLETED` or `ERROR`. See [Status enums reference](/v3/references/glossary#status-enums).

## Amount precision

| Currency type | Max decimals | Example         | Over-precision error                      |
| ------------- | ------------ | --------------- | ----------------------------------------- |
| Fiat          | 2            | `"1000.00"`     | `422 WITHDRAWAL_INVALID_AMOUNT_PRECISION` |
| Crypto        | 6            | `"1000.000001"` | `422 WITHDRAWAL_INVALID_AMOUNT_PRECISION` |

Amounts are JSON **strings**, never numbers. Regex: `^-?[0-9]+(\.[0-9]{1,8})?$`. See [Amounts](/v3/amounts).

## Idempotency TTLs

| Endpoint                  | TTL    | Reason                                                                                                |
| ------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
| `POST /v3/fx/quotes`      | 30 min | Duplicates are cheap (re-quote)                                                                       |
| `POST /v3/fx/trades`      | 24 h   | Duplicates move thousands of dollars                                                                  |
| `POST /v3/fx/withdrawals` | 7 days | Carries v2's window forward — sized for long-running rails (SWIFT, weekend ACH, end-of-month batches) |

See [Idempotency](/v3/idempotency).

## Pagination

The unbounded lists (`trades`, `deposits`, `withdrawals`) use cursor pagination, newest-first by `createdAt`. Default page size is **25** and the maximum is **100**. Their responses wrap `{data, pagination: {limit, hasNext, nextCursor, hasPrev, prevCursor}}`; cursors are opaque tokens that you pass back verbatim. The bounded lists (`pairs`, `balances`, `withdrawal-accounts`) return their complete `data` array without pagination parameters or a `pagination` object. No endpoint uses `total_count` or page numbers.

| Param           | Type                              |
| --------------- | --------------------------------- |
| `limit`         | int 1–100                         |
| `startingAfter` | opaque cursor string (older than) |
| `endingBefore`  | opaque cursor string (newer than) |

See [Pagination](/v3/pagination).

## Error response shape

```json theme={null}
{
  "error": {
    "code": "QUOTE_EXPIRED",
    "type": "CONFLICT",
    "message": "The quoted rate has expired. Please request a new quote.",
    "retryStrategy": "FIX_AND_RESUBMIT",
    "details": {
      "quoteId": "qte_3FfGK34vwMvVFDedyb2nkf",
      "expiredAt": "2026-04-28T10:00:00.000Z"
    }
  }
}
```

`code`, `type`, `message`, `retryStrategy`, and `details` are **all required** on every v3 error response (`details` is `{}` when there's no structured context). `code` is stable across versions; `message` may change. Branch on `code` and `type` for behavior, or read `retryStrategy` directly for retry handling — never branch on `message`. For body-portable correlation, capture the `X-Trace-Id` header at call time. Full catalog: [Errors](/v3/errors).

## HTTP status × type quick map

| Status | Typical `type`                  | Meaning                                                                                                                                                          |
| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `VALIDATION_ERROR`              | Malformed JSON, wrong types                                                                                                                                      |
| 401    | `AUTHENTICATION_ERROR`          | Token missing/invalid/expired                                                                                                                                    |
| 403    | `AUTHORIZATION_ERROR`           | Auth ok, not allowed                                                                                                                                             |
| 404    | `NOT_FOUND`                     | Resource missing (also covers cross-org leakage prevention)                                                                                                      |
| 409    | `CONFLICT`                      | State-driven conflict (insufficient balance, in-flight key)                                                                                                      |
| 422    | `VALIDATION_ERROR` / `CONFLICT` | Semantic violation; idempotency-mismatch                                                                                                                         |
| 428    | `VALIDATION_ERROR`              | Missing `Idempotency-Key` on a write                                                                                                                             |
| 429    | `RATE_LIMITED`                  | Throttled                                                                                                                                                        |
| 500    | `INTERNAL_ERROR`                | `INTERNAL_ERROR` catch-all; write-path 500s (`TRADE_EXECUTION_FAILED`, `WITHDRAWAL_INITIATION_FAILED`) echo `details.resourceId` for safe check-state-then-retry |

## What's next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/v3/quickstart">
    5-minute round trip from JWT to executed trade.
  </Card>

  <Card title="API reference" icon="code" href="/v3/api-reference/trade/list-currency-pairs">
    Full schemas with the interactive playground.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/v3/errors">
    Every documented error code with retry semantics.
  </Card>

  <Card title="Migration from v2" icon="arrow-right-arrow-left" href="/v3/migration-from-v2">
    Field renames and the breaking changes that matter.
  </Card>
</CardGroup>
