{"openapi":"3.1.0","info":{"title":"CrestRate API","version":"1.0.0","description":"CrestRate is a foreign-exchange rate API for businesses that charge or pay across currencies. It aggregates multiple independent rate sources and returns the rate most favourable to the caller, clamped relative to the live market.\n\n**Authentication.** Every `/v1` endpoint requires an API key, sent as `X-API-Key: <key>` or `Authorization: Bearer <key>`. Create keys in the dashboard. `/health` and `/openapi.json` need no key.\n\n**Choose the side with `strategy`.** `max` (default, side `charge`) picks the highest rate for collecting from customers; `min` (side `pay`) picks the lowest rate for paying out; `median` (side `charge`) is neutral. The selected rate is capped (`cap_rate`) and floored (`floor_rate`) relative to the freshest market anchor.\n\n**Markup is configured per API key** in the dashboard: a default in basis points (0 to 1000, 100 bps = 1%) plus optional overrides per `quote` currency. Precedence: key currency override, then key default, then platform default. Changes apply from the next request; quotes already created keep the markup locked in at creation. Markup follows the side: it raises the rate when charging and lowers it when paying. Where markups must be disclosed (for example consumer payments in the EU), disclose yours to your customers.\n\n**Every rate and amount is a string, not a JSON number.** JSON numbers are IEEE-754 doubles and lose precision, which corrupts money calculations. Parse them with a decimal type.\n\n**Currencies.** Available now: USD, JPY, EUR, HKD, CNY. TWD, SGD, GBP, AUD, KRW, MYR, THB: real-time data temporarily unavailable; requests using them return HTTP 422 `currency_not_available` and will open once live data is stable. Unknown codes return HTTP 400 `unsupported_currency`.\n\n**Limits.** Rate limit and monthly quota apply per account: all API keys of an account share one token bucket and one monthly quota according to the plan (see the `X-RateLimit-*` and `X-Quota-*` headers, which report the account's figures). Exceeding the monthly quota returns HTTP 429 `quota_exceeded`, a hard block with no overage billing. Every `/v1` response, including errors, carries the `X-RateLimit-*` and `X-Quota-*` headers and an `X-Request-Id` for support.\n\n**Errors** use one shape: `{\"error\": \"<code>\", \"message\": \"<English text>\"}` plus documented extra fields. Match on `error`, never on `message`.","contact":{"url":"https://crestrate.com/quickstart","email":"support@crestrate.com"},"termsOfService":"https://crestrate.com/legal/terms"},"servers":[{"url":"https://api.crestrate.com"}],"security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"tags":[{"name":"rates","description":"Exchange rate lookup"},{"name":"quotes","description":"Locked quotes"},{"name":"ops","description":"Data sources and service health"}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer","description":"The API key sent as `Authorization: Bearer <key>`"}},"schemas":{"Rate":{"type":"object","properties":{"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Final rate. Use this to calculate the amount. `raw_rate x (1 + markup_bps/10000)` when side is `charge`, `raw_rate x (1 - markup_bps/10000)` when side is `pay`"},"raw_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Selected rate before markup, after the cap or floor"},"mid_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Median of valid sources, approximately the market mid"},"low_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Lowest valid source rate"},"high_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Highest valid source rate"},"markup_bps":{"type":"integer","minimum":0,"maximum":1000,"description":"Markup applied, in basis points (100 bps = 1%)"},"strategy":{"type":"string","enum":["max","median","min"],"description":"Which side the rate favours. `max` (default): side `charge`, the highest valid rate. `min`: side `pay`, the lowest valid rate. `median`: side `charge`, the source closest to the median"},"chosen_provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"source_count":{"type":"integer","minimum":0,"description":"Number of valid sources used"},"spread_vs_mid_pct":{"type":"string","pattern":"^-?\\d+\\.\\d{4}$","example":"0.1234","description":"Deviation of the final rate from the mid rate, in percent. Usually positive when charging and negative when paying"},"anchor_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Freshness anchor"},"anchor_tier":{"type":"string","enum":["realtime","hourly","daily","all","identity"],"description":"Tier the anchor came from. `daily` or `all` means the freshest sources are temporarily unavailable; `identity` is used for same-currency pairs"},"anchor_notes":{"type":"array","items":{"type":"string"},"description":"English notes on why fresher tiers were not used as the anchor"},"cap_rate":{"type":["string","null"],"pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Maximum selected rate allowed relative to the anchor. Null for same-currency pairs"},"floor_rate":{"type":["string","null"],"pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Minimum selected rate allowed relative to the anchor. Null for same-currency pairs"},"capped":{"type":"boolean","description":"True when the selected rate exceeded the cap and was reduced to it"},"floored":{"type":"boolean","description":"True when the selected rate was below the floor and was raised to it"},"side":{"type":"string","enum":["charge","pay"],"description":"Side the rate was chosen for. `charge` (strategies `max` and `median`): markup raises the rate and amounts round up. `pay` (strategy `min`): markup lowers the rate and amounts round down"},"markup_source":{"type":"string","enum":["key_currency","key_default","platform","none"],"description":"Where `markup_bps` came from: the calling key's override for this `quote` currency, the key's default markup, the platform default, or `none` for same-currency pairs"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/SourceDetail"}},"generated_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"generated_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"}},"required":["base","quote","rate","raw_rate","mid_rate","low_rate","high_rate","markup_bps","strategy","chosen_provider","source_count","spread_vs_mid_pct","anchor_rate","anchor_tier","anchor_notes","cap_rate","floor_rate","capped","floored","side","markup_source","sources","generated_at","generated_at_unix"]},"SourceDetail":{"type":"object","properties":{"provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Stable anonymous source ID, e.g. `source_a`"},"label":{"type":"string","example":"Source A","description":"Display name, e.g. `Source A`"},"data_freq":{"type":["string","null"],"enum":["realtime","hourly","daily",null],"description":"How often this source's own data updates"},"rate":{"type":["string","null"],"pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Rate reported by this source. Null when the source does not cover the pair"},"vs_anchor_pct":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{4}$","example":"0.1234","description":"Deviation from the anchor, in percent"},"fetched_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"When we fetched this source"},"age_seconds":{"type":"number","description":"Seconds since we fetched this source"},"source_time":{"type":["string","null"],"format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"Publication time reported by the source itself. Null when not provided"},"used":{"type":"boolean","description":"Whether this source was used"},"chosen":{"type":"boolean","description":"Whether this source provided the final rate"},"excluded_code":{"type":["string","null"],"enum":["missing_currency","snapshot_stale","deviates_from_anchor",null],"description":"Machine-readable reason the source was excluded, or null when it was used"},"excluded_reason":{"type":["string","null"],"description":"Human-readable English reason the source was excluded, or null. Wording may change"}},"required":["provider","label","data_freq","rate","vs_anchor_pct","fetched_at","age_seconds","source_time","used","chosen","excluded_code","excluded_reason"]},"Error":{"type":"object","properties":{"error":{"type":"string","enum":["bad_request","unsupported_currency","api_key_required","invalid_api_key","account_disabled","email_not_verified","not_found","payload_too_large","currency_not_available","rate_limited","quota_exceeded","internal_error","no_rate","storage_unavailable"],"description":"Machine-readable error code. Match on this in monitoring rules, not on `message`"},"message":{"type":"string","description":"Human-readable English description. Wording may change"},"currency":{"type":"string","description":"The offending currency code"},"supported":{"type":"array","items":{"type":"string"},"description":"Currencies currently available (with `currency_not_available`)"},"retry_after":{"type":"number","description":"Seconds to wait before retrying"},"used":{"type":"integer","description":"Requests used this month"},"quota":{"type":"integer","description":"Monthly quota"},"upgrade_url":{"type":"string","description":"Absolute URL of the pricing page"}},"required":["error","message"]},"Rates":{"type":"object","properties":{"rows":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/RatesRow"},{"$ref":"#/components/schemas/RatesRowError"}]}},"generated_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"generated_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"}},"required":["rows","generated_at","generated_at_unix"]},"RatesRow":{"type":"object","properties":{"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"final_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"raw_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"mid_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"chosen_provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"source_count":{"type":"integer","minimum":0},"markup_bps":{"type":"integer","minimum":0,"maximum":1000,"description":"Markup applied, in basis points (100 bps = 1%)"},"spread_pct":{"type":"string","pattern":"^-?\\d+\\.\\d{3}$","example":"0.123","description":"Percentage as a decimal string with 3 decimal places"},"anchor_tier":{"type":"string","enum":["realtime","hourly","daily","all","identity"],"description":"Tier the anchor came from. `daily` or `all` means the freshest sources are temporarily unavailable; `identity` is used for same-currency pairs"},"capped":{"type":"boolean"},"error":{"type":"null"}},"required":["base","quote","final_rate","raw_rate","mid_rate","chosen_provider","source_count","markup_bps","spread_pct","anchor_tier","capped","error"]},"RatesRowError":{"type":"object","properties":{"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"error":{"type":"string","description":"English reason this pair has no rate (sources are anonymised)"}},"required":["base","quote","error"]},"Convert":{"type":"object","properties":{"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Amount as a decimal string, not a JSON number"},"payable":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Converted amount, rounded to the currency's smallest unit in your favour: up when side is `charge`, down when side is `pay`"},"rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"mid_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"mid_payable":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Amount at the mid rate, for comparison"},"gain_vs_mid":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Difference in your favour versus the mid rate; larger is better. `payable - mid_payable` when charging, `mid_payable - payable` when paying"},"markup_bps":{"type":"integer","minimum":0,"maximum":1000,"description":"Markup applied, in basis points (100 bps = 1%)"},"chosen_provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"source_count":{"type":"integer","minimum":0},"anchor_tier":{"type":"string","enum":["realtime","hourly","daily","all","identity"],"description":"Tier the anchor came from. `daily` or `all` means the freshest sources are temporarily unavailable; `identity` is used for same-currency pairs"},"capped":{"type":"boolean"},"floored":{"type":"boolean"},"side":{"type":"string","enum":["charge","pay"],"description":"Side the rate was chosen for. `charge` (strategies `max` and `median`): markup raises the rate and amounts round up. `pay` (strategy `min`): markup lowers the rate and amounts round down"},"markup_source":{"type":"string","enum":["key_currency","key_default","platform","none"],"description":"Where `markup_bps` came from: the calling key's override for this `quote` currency, the key's default markup, the platform default, or `none` for same-currency pairs"}},"required":["base","quote","amount","payable","rate","mid_rate","mid_payable","gain_vs_mid","markup_bps","chosen_provider","source_count","anchor_tier","capped","floored","side","markup_source"]},"Quote":{"type":"object","properties":{"quote_id":{"type":"string","pattern":"^[0-9a-f]{32}$","description":"Keep this for retrieval and reconciliation"},"reference":{"type":["string","null"],"description":"Your order ID, echoed back"},"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Amount as a decimal string, not a JSON number"},"payable":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Locked amount. Does not change before expiry. Rounded up when side is `charge`, down when `pay`"},"rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"raw_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"mid_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"markup_bps":{"type":"integer","minimum":0,"maximum":1000,"description":"Markup locked in when the quote was created, in basis points"},"strategy":{"type":"string","enum":["max","median","min"],"description":"Which side the rate favours. `max` (default): side `charge`, the highest valid rate. `min`: side `pay`, the lowest valid rate. `median`: side `charge`, the source closest to the median"},"side":{"type":"string","enum":["charge","pay"],"description":"Side the rate was chosen for. `charge` (strategies `max` and `median`): markup raises the rate and amounts round up. `pay` (strategy `min`): markup lowers the rate and amounts round down"},"chosen_provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"source_count":{"type":"integer","minimum":0},"created_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"created_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"},"expires_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"After this the quote returns 404"},"expires_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"},"ttl_seconds":{"type":"integer","exclusiveMinimum":0}},"required":["quote_id","reference","base","quote","amount","payable","rate","raw_rate","mid_rate","markup_bps","strategy","side","chosen_provider","source_count","created_at","created_at_unix","expires_at","expires_at_unix","ttl_seconds"]},"QuoteCreateRequest":{"type":"object","properties":{"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"Alias: `from`"},"from":{"type":"string","description":"Alias of `base`"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"Alias: `to`"},"to":{"type":"string","description":"Alias of `quote`"},"amount":{"anyOf":[{"type":"string"},{"type":"number"}],"description":"Price in the base currency. A decimal string is recommended; must be > 0"},"reference":{"type":["string","null"],"maxLength":128,"description":"Your own order ID, echoed back for reconciliation (max 128 characters)"},"strategy":{"type":"string","enum":["max","median","min"],"description":"Same as the `strategy` query"}},"required":["amount"]},"QuoteLookup":{"type":"object","properties":{"quote_id":{"type":"string","pattern":"^[0-9a-f]{32}$","description":"Keep this for retrieval and reconciliation"},"reference":{"type":["string","null"],"description":"Your order ID, echoed back"},"base":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"quote":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"description":"ISO 4217 currency code. Only currencies with live data are accepted"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Amount as a decimal string, not a JSON number"},"payable":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$","example":"1234.50","description":"Locked amount. Does not change before expiry. Rounded up when side is `charge`, down when `pay`"},"rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"raw_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"mid_rate":{"type":"string","pattern":"^\\d+\\.\\d{8}$","example":"7.81234567","description":"Decimal string with 8 decimal places, not a JSON number (avoids floating-point precision loss)"},"markup_bps":{"type":"integer","minimum":0,"maximum":1000,"description":"Markup locked in when the quote was created, in basis points"},"strategy":{"type":"string","enum":["max","median","min"],"description":"Which side the rate favours. `max` (default): side `charge`, the highest valid rate. `min`: side `pay`, the lowest valid rate. `median`: side `charge`, the source closest to the median"},"side":{"type":"string","enum":["charge","pay"],"description":"Side the rate was chosen for. `charge` (strategies `max` and `median`): markup raises the rate and amounts round up. `pay` (strategy `min`): markup lowers the rate and amounts round down"},"chosen_provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"source_count":{"type":"integer","minimum":0},"created_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"created_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"},"expires_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"After this the quote returns 404"},"expires_at_unix":{"type":"number","description":"Unix time in seconds (may be fractional)"},"ttl_seconds":{"type":"integer","exclusiveMinimum":0},"expired":{"type":"boolean","description":"Whether the quote has expired"}},"required":["quote_id","reference","base","quote","amount","payable","rate","raw_rate","mid_rate","markup_bps","strategy","side","chosen_provider","source_count","created_at","created_at_unix","expires_at","expires_at_unix","ttl_seconds","expired"]},"Sources":{"type":"object","properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/SourceSummary"}},"source_count":{"type":"integer","minimum":0},"last_poll_at":{"type":["string","null"],"format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"}},"required":["sources","source_count","last_poll_at"]},"SourceSummary":{"type":"object","properties":{"provider":{"type":"string","pattern":"^(source_[a-z]+|identity)$","example":"source_a","description":"Anonymous source ID, e.g. `source_a`; `identity` for same-currency"},"label":{"type":"string"},"data_freq":{"type":"string","enum":["realtime","hourly","daily"],"description":"How often this source's own data updates"},"last_fetch_at":{"type":["string","null"],"format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"last_fetch_age":{"type":["number","null"],"description":"Seconds since the last fetch"},"source_time":{"type":["string","null"],"format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"},"source_age_seconds":{"type":["number","null"]},"currencies":{"type":"integer","minimum":0,"description":"Number of supported currencies this source currently covers"}},"required":["provider","label","data_freq","last_fetch_at","last_fetch_age","source_time","source_age_seconds","currencies"]},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"sources_healthy":{"type":"integer","minimum":0},"last_updated_at":{"type":["string","null"],"format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$","example":"2026-09-14T10:38:01Z","description":"ISO 8601 timestamp in UTC"}},"required":["status","sources_healthy","last_updated_at"]}},"parameters":{}},"paths":{"/v1/rate":{"get":{"operationId":"getRate","tags":["rates"],"summary":"Rate for one currency pair, favouring your side, with per-source detail","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"USD","description":"Currency the price is set in. Required (or its alias `from`)"},"required":false,"description":"Currency the price is set in. Required (or its alias `from`)","name":"base","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"USD","description":"Alias of `base`"},"required":false,"description":"Alias of `base`","name":"from","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"JPY","description":"Settlement currency: what the customer pays in when charging, or what you pay out in when paying. Required (or its alias `to`)"},"required":false,"description":"Settlement currency: what the customer pays in when charging, or what you pay out in when paying. Required (or its alias `to`)","name":"quote","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"JPY","description":"Alias of `quote`"},"required":false,"description":"Alias of `quote`","name":"to","in":"query"},{"schema":{"type":"string","default":"max","enum":["max","median","min"],"description":"Which side the rate favours (case-insensitive). `max` (default): side `charge`, the highest valid rate, for collecting from customers. `min`: side `pay`, the lowest valid rate, for paying out. `median`: side `charge`, the source closest to the median, for bookkeeping. The side also sets the markup direction and how `payable` is rounded."},"required":false,"description":"Which side the rate favours (case-insensitive). `max` (default): side `charge`, the highest valid rate, for collecting from customers. `min`: side `pay`, the lowest valid rate, for paying out. `median`: side `charge`, the source closest to the median, for bookkeeping. The side also sets the markup direction and how `payable` is rounded.","name":"strategy","in":"query"}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rate"}}}},"400":{"description":"`bad_request`: a parameter is missing or invalid. `unsupported_currency`: the currency code is unknown","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`currency_not_available`: real-time data for this currency is temporarily unavailable; `supported` lists the currencies you can use now. Do not retry","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`no_rate`: not enough valid sources. The API returns no rate rather than an untrustworthy one; never treat this as zero. `storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/rates":{"get":{"operationId":"listRates","tags":["rates"],"summary":"Rate table for several currency pairs","description":"Returns one row per `base` x `quote` pair using the platform default markup (the calling key's markup is not applied). A pair that cannot be priced returns a row with only `base`, `quote` and `error`; the other rows are unaffected. An unknown currency fails the request with 400 `unsupported_currency`, a temporarily unavailable one with 422 `currency_not_available`. The whole `base` list is checked before `quote`: within one list an unknown code takes precedence, but a problem in `base` is always reported first, so an unavailable currency in `base` combined with `quote=ZZZ` returns 422.","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","example":"USD,EUR","description":"Comma-separated base currencies. Defaults to the configured product currencies"},"required":false,"description":"Comma-separated base currencies. Defaults to the configured product currencies","name":"base","in":"query"},{"schema":{"type":"string","example":"JPY,HKD","description":"Comma-separated quote currencies. Defaults to the configured payment currencies"},"required":false,"description":"Comma-separated quote currencies. Defaults to the configured payment currencies","name":"quote","in":"query"}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rates"}}}},"400":{"description":"`bad_request`: a parameter is missing or invalid. `unsupported_currency`: the currency code is unknown","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`currency_not_available`: real-time data for this currency is temporarily unavailable; `supported` lists the currencies you can use now. Do not retry","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/convert":{"get":{"operationId":"convert","tags":["rates"],"summary":"Convert an amount, rounded to the currency's smallest unit in your favour","description":"For display and estimation only. Use `POST /v1/quotes` when taking payment.","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"USD","description":"Currency the price is set in. Required (or its alias `from`)"},"required":false,"description":"Currency the price is set in. Required (or its alias `from`)","name":"base","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"USD","description":"Alias of `base`"},"required":false,"description":"Alias of `base`","name":"from","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"JPY","description":"Settlement currency: what the customer pays in when charging, or what you pay out in when paying. Required (or its alias `to`)"},"required":false,"description":"Settlement currency: what the customer pays in when charging, or what you pay out in when paying. Required (or its alias `to`)","name":"quote","in":"query"},{"schema":{"type":"string","enum":["USD","JPY","EUR","HKD","CNY"],"example":"JPY","description":"Alias of `quote`"},"required":false,"description":"Alias of `quote`","name":"to","in":"query"},{"schema":{"type":"string","example":"100","description":"Price in the base currency, as a decimal string. Required; must be greater than 0"},"required":false,"description":"Price in the base currency, as a decimal string. Required; must be greater than 0","name":"amount","in":"query"},{"schema":{"type":"string","default":"max","enum":["max","median","min"],"description":"Which side the rate favours (case-insensitive). `max` (default): side `charge`, the highest valid rate, for collecting from customers. `min`: side `pay`, the lowest valid rate, for paying out. `median`: side `charge`, the source closest to the median, for bookkeeping. The side also sets the markup direction and how `payable` is rounded."},"required":false,"description":"Which side the rate favours (case-insensitive). `max` (default): side `charge`, the highest valid rate, for collecting from customers. `min`: side `pay`, the lowest valid rate, for paying out. `median`: side `charge`, the source closest to the median, for bookkeeping. The side also sets the markup direction and how `payable` is rounded.","name":"strategy","in":"query"}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Convert"}}}},"400":{"description":"`bad_request`: a parameter is missing or invalid. `unsupported_currency`: the currency code is unknown","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`currency_not_available`: real-time data for this currency is temporarily unavailable; `supported` lists the currencies you can use now. Do not retry","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`no_rate`: not enough valid sources. The API returns no rate rather than an untrustworthy one; never treat this as zero. `storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/quotes":{"post":{"operationId":"createQuote","tags":["quotes"],"summary":"Create a locked quote. Use this when taking payment, not /v1/convert","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Quote parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteCreateRequest"}}}},"responses":{"201":{"description":"Created","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"description":"`bad_request`: a parameter is missing or invalid. `unsupported_currency`: the currency code is unknown","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`payload_too_large`: the request body is too large","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`currency_not_available`: real-time data for this currency is temporarily unavailable; `supported` lists the currencies you can use now. Do not retry","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`no_rate`: not enough valid sources. The API returns no rate rather than an untrustworthy one; never treat this as zero. `storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"description":"There is a gap between showing a customer a price and receiving payment, and the rate moves in that gap. A quote freezes the payable amount for 900 seconds. The calling key's markup is locked into the quote at creation; changing the markup later does not affect quotes already issued."}},"/v1/quotes/{quote_id}":{"get":{"operationId":"getQuote","tags":["quotes"],"summary":"Retrieve a locked quote","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","example":"4ac06023a7e14237bc986ed9bae42878","description":"32-character lowercase hex quote ID"},"required":true,"description":"32-character lowercase hex quote ID","name":"quote_id","in":"path"}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteLookup"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: the quote does not exist or has been removed after expiry","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sources":{"get":{"operationId":"listSources","tags":["ops"],"summary":"Active data sources with fetch time and each source's own publication time","security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sources"}}}},"401":{"description":"`api_key_required`: no API key was sent. `invalid_api_key`: the key is invalid or revoked","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`account_disabled` or `email_not_verified`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: slow down and retry after `Retry-After` seconds. `quota_exceeded`: the monthly quota is exhausted; this is a hard block with no overage billing, so retrying will not help until the next calendar month (UTC) or an upgrade (`upgrade_url`)","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"},"Retry-After":{"schema":{"type":"string","description":"Seconds to wait before retrying. Sent with `rate_limited` only"},"required":false,"description":"Seconds to wait before retrying. Sent with `rate_limited` only"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`storage_unavailable`: temporary; retry with backoff","headers":{"X-RateLimit-Limit":{"schema":{"type":"string","description":"Token bucket capacity (maximum burst)"},"required":true,"description":"Token bucket capacity (maximum burst)"},"X-RateLimit-Remaining":{"schema":{"type":"string","description":"Tokens currently remaining"},"required":true,"description":"Tokens currently remaining"},"X-RateLimit-Reset":{"schema":{"type":"string","description":"Unix time (seconds) when the next token becomes available"},"required":true,"description":"Unix time (seconds) when the next token becomes available"},"X-Quota-Limit":{"schema":{"type":"string","description":"Monthly quota. 0 means unlimited"},"required":true,"description":"Monthly quota. 0 means unlimited"},"X-Quota-Used":{"schema":{"type":"string","description":"Requests used this month"},"required":true,"description":"Requests used this month"},"X-Quota-Remaining":{"schema":{"type":"string","description":"Requests remaining this month"},"required":true,"description":"Requests remaining this month"},"X-Request-Id":{"schema":{"type":"string","description":"Request ID for support and log correlation"},"required":true,"description":"Request ID for support and log correlation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"operationId":"health","tags":["ops"],"summary":"Health check (no authentication required)","description":"Healthy means the service can price: storage is reachable and enough sources have fresh snapshots. Both states return the same body.","security":[],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"Degraded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}}},"webhooks":{}}