Skip to main content
POST
/
v1
/
fx
/
quote
Create a lockable FX quote
curl --request POST \
  --url https://api.antonpayments.com/v1/fx/quote \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'DPoP: <api-key>' \
  --data '
{
  "sell_currency": "USD",
  "buy_currency": "USD",
  "sell_amount": "1234.56",
  "buy_amount": "1234.56",
  "locked": true
}
'
{
  "id": "<string>",
  "merchant_id": "<string>",
  "sell_currency": "USD",
  "buy_currency": "USD",
  "sell_amount": "1234.56",
  "buy_amount": "1234.56",
  "mid_market_rate": "1234.56",
  "customer_rate": "1234.56",
  "locked": true,
  "created_at": "2026-04-15T14:30:00Z",
  "inverse_rate": "1234.56",
  "fx_markup_bps": 123,
  "fx_fee": "1234.56",
  "fx_fee_currency": "USD",
  "provider": "<string>",
  "provider_ref": "<string>",
  "expires_at": "2026-04-15T14:30:00Z",
  "lock_id": "<string>",
  "lock_expires_at": "2026-04-15T14:30:00Z"
}

Documentation Index

Fetch the complete documentation index at: https://docs.antonpayments.com/llms.txt

Use this file to discover all available pages before exploring further.

Authorizations

Authorization
string
header
required

OAuth 2.0 client_credentials grant (RFC 6749 §4.4) bound to a DPoP keypair (RFC 9449).

Flow (every authenticated /v1 call requires both an access token AND a fresh per-request DPoP proof):

  1. Register a credential via the merchant portal. Anton issues a client_id (ant_oc_<env>_<32hex>) and a client_secret (ant_ocs_<env>_<48hex>, shown ONCE). The portal generates an ES256 or Ed25519 DPoP keypair in your browser; you store the private half.
  2. Mint an access token: POST /oauth/token with Authorization: Basic <client_id:client_secret> and Content-Type: application/x-www-form-urlencoded. Body: grant_type=client_credentials. A DPoP header carrying a proof signed for the token endpoint is required (no ath claim on this proof).
  3. Use the token: send Authorization: DPoP <access_token> plus a fresh DPoP: <proof> header on every /v1 request. The proof JWT MUST carry htm (request method), htu (request URL, no query/fragment), iat (within ±60s), jti (unique within 5 min), and ath (SHA-256 of the access token, base64url).

Tokens expire in 1 hour in production / staging and 8 hours in sandbox. There are no refresh tokens — call /oauth/token again with your secret. Anton's public signing key is published at /.well-known/jwks.json.

OpenAPI 3.0 has no native DPoP scheme; this declaration plus dpopHeader together convey both the access-token Authorization and the per-request proof header.

DPoP
string
header
required

Per-request DPoP proof JWT (RFC 9449). MUST accompany the Authorization: DPoP <access_token> header on every protected operation. The proof is signed by the merchant's private DPoP key and carries htm, htu, iat, jti, and ath claims.

Body

application/json

Supply either sell_amount OR buy_amount — the missing side is computed from the locked rate.

sell_currency
string
required

ISO 4217 three-letter currency code.

Pattern: ^[A-Z]{3}$
Example:

"USD"

buy_currency
string
required

ISO 4217 three-letter currency code.

Pattern: ^[A-Z]{3}$
Example:

"USD"

sell_amount
string

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

buy_amount
string

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

locked
boolean
default:true

Request a rate-locked quote whose customer_rate is held until lock_expires_at. Redeem the lock by passing the returned id (or equivalently lock_id) as quote_id on POST /v1/fx/exchange before expiry. Defaults to true. Set to false for an indicative (non-binding) quote that cannot be redeemed on /v1/fx/exchange.

Response

Quote created.

An FX rate quote, optionally locked for execution.

id
string
required
Pattern: ^fxq_[a-zA-Z0-9]+$
merchant_id
string
required
sell_currency
string
required

ISO 4217 three-letter currency code.

Pattern: ^[A-Z]{3}$
Example:

"USD"

buy_currency
string
required

ISO 4217 three-letter currency code.

Pattern: ^[A-Z]{3}$
Example:

"USD"

sell_amount
string
required

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

buy_amount
string
required

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

mid_market_rate
string
required

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

customer_rate
string
required

Mid-market adjusted by your pricing plan's FX markup.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

locked
boolean
required
created_at
string<date-time>
required

RFC 3339 / ISO 8601 timestamp in UTC.

Example:

"2026-04-15T14:30:00Z"

inverse_rate
string

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

fx_markup_bps
integer
fx_fee
string

Decimal amount as a string, never a float. Up to 12 whole digits.

Pattern: ^-?\d{1,12}(\.\d+)?$
Example:

"1234.56"

fx_fee_currency
string

ISO 4217 three-letter currency code.

Pattern: ^[A-Z]{3}$
Example:

"USD"

provider
string
provider_ref
string
expires_at
string<date-time>

RFC 3339 / ISO 8601 timestamp in UTC.

Example:

"2026-04-15T14:30:00Z"

lock_id
string

Identifier of the rate lock. Pass this value as quote_id on POST /v1/fx/exchange to redeem the locked rate before lock_expires_at. Equal to id on locked quotes, and omitted entirely on indicative quotes (locked: false).

Pattern: ^fxq_[a-zA-Z0-9]+$
lock_expires_at
string<date-time>

UTC timestamp past which the rate lock is no longer honored. Omitted on indicative quotes. Equal to expires_at on locked quotes — kept as a dedicated field so clients can distinguish "the quote payload expired" from "the merchant's rate lock expired" when those semantics diverge in future revisions.

Example:

"2026-04-15T14:30:00Z"