本頁目錄
CrestRate API 文件
多來源彙整的匯率 API,為跨幣別收款與付款的企業打造。你決定匯率站在哪一邊,點差依 API key 設定,報價單同時鎖定匯率與點差。
- 基礎 URL —
https://api.crestrate.com。匯率端點都在/v1之下,例如https://api.crestrate.com/v1/rate - 第一次串接 — 請先看快速入門,四段可直接複製的程式碼帶你完成第一次呼叫
- 機器可讀規格 — OpenAPI 3.1
- 方案、配額與速率限制 — 定價
- 服務狀態 — https://crestrate.com/zh-hant/status
適用情境
以一種貨幣標價、以另一種貨幣結算,就用得上。我們不依產業區分客戶,常見用法如下:
- 跨境電商 — 商品標價換算成客戶的貨幣
- SaaS 與訂閱制 — 依客戶當地貨幣開立帳單
- 訪日旅客消費 — 飯店、零售、免稅店、收銀系統以日圓定價,旅客以港幣、人民幣、美元、歐元付款
- B2B 進出口貿易 — 依買方貨幣開立發票,報價有效期內以報價單鎖定匯率
- 平台與市集 — 向買家收款用
strategy=max,給賣家結算用strategy=min - 旅遊、留學、簽證等代辦 — 依客戶的貨幣報價
- 遊戲與數位商品 — 依地區定價
支援的幣別
以下幣別提供即時資料,base 與 quote 可任意組合:
| 幣別 | 代碼 | 金額最小單位 |
|---|---|---|
| 美元 | USD |
0.01 |
| 日圓 | JPY |
1 |
| 歐元 | EUR |
0.01 |
| 港幣 | HKD |
0.01 |
| 人民幣 | CNY |
0.01 |
暫時無法提供即時資料: TWD、SGD、GBP、AUD、KRW、MYR、THB,穩定後開放。
在此之前,請求中使用這些代碼會回傳 HTTP 422 currency_not_available,supported 欄位列出目前可用的幣別。完全無法辨識的代碼回傳 HTTP 400 unsupported_currency。請求中的幣別代碼不區分大小寫,回應中一律為大寫。
匯率是怎麼選出來的
每次請求都會把目前健康的全部資料來源一起納入計算,而不是只問一家:
- 各來源的匯率表統一正規化為同一基準,你要的貨幣對以交叉匯率算出
- 資料過期的來源、未涵蓋該貨幣對的來源,先行剔除
- 從最新的那一級來源(即時 → 每小時 → 每日)取中位數作為基準。 這是對「目前市場價格」最可靠的估計
- 與基準偏離超過故障門檻的來源會被判定為資料損壞,予以剔除
- 依
strategy在剩下的來源中選價:max取最高、min取最低、median取最接近中位數者。 再做雙向鉗制:高於封頂線cap_rate就壓回封頂線,低於保底線floor_rate就拉回保底線 - 依收付方向套用點差:收款方往上加,付款方往下減
回應中一律註明最終匯率來自哪個來源、其他來源各報多少,以及任何被剔除的來源與機器可讀的剔除原因(excluded_code)。資料來源以穩定的匿名代號標示,例如 source_a。
有效來源不足時回傳 HTTP 503 no_rate,而不是給出一個我們無法擔保的數字。
你決定匯率站在哪一邊
同一個貨幣對,收款時匯率越高越好,付款時越低越好。用 strategy 告訴我們你在哪一邊,回應中的 side 會註明本次依哪一邊計算。
strategy |
side |
對誰有利 | 典型用途 |
|---|---|---|---|
max(預設) |
charge |
收款方:選最高匯率,同樣的標價收到更多 | 電商、SaaS、飯店、B2B 開立發票 |
min |
pay |
付款方:選最低匯率,同樣的應付金額付出更少 | 平台給賣家結算、支付海外供應商 |
median |
charge |
中立:選最接近各來源中位數的匯率 | 會計記帳、內部報表 |
strategy 不區分大小寫,其他值回傳 HTTP 400 bad_request。side 同時決定點差方向與金額取整方向:
| 項目 | charge(收款方) |
pay(付款方) |
|---|---|---|
| 點差 | 匯率往上,客戶多付 | 匯率往下,你少付 |
payable 取整 |
無條件進位到最小貨幣單位 | 無條件捨去到最小貨幣單位 |
gain_vs_mid |
payable - mid_payable(多收的) |
mid_payable - payable(少付的) |
兩個方向都有保護。 選出的匯率會與新鮮度基準 anchor_rate 比較:高於封頂線 cap_rate 就壓回(capped: true),低於保底線 floor_rate 就拉回(floored: true)。收款時不會明顯高於即時市場,付款時不會明顯低於即時市場 —— 對方拿公開匯率核對也站得住腳。點差是你主動設定的,在鉗制之後才套用。
點差
點差是你在選出的匯率上額外加上的幅度,單位為基點(bps),100 基點 = 1%。
| 項目 | 說明 |
|---|---|
| 在哪裡設定 | 控制台的 API key 列表,每把 key 個別設定 |
| 預設點差 | 這把 key 在所有幣別上使用的點差 |
| 依幣別個別設定 | 依 quote 幣別覆寫預設點差,例如 HKD 120 基點、JPY 200 基點。只能為提供即時資料的幣別個別設定 |
| 設定範圍 | 0 ~ 1000 基點(0% ~ 10%)。設為 0 表示明確不加點差 |
| 生效時間 | 儲存後立即生效,下一次請求就使用新值 |
| 報價單 | 點差在建立報價單時鎖定。之後修改點差,已發出的報價單不受影響 |
優先順序由高到低,回應中的 markup_source 會註明本次使用的是哪一個:
- 該 key 對此幣別的個別設定 →
key_currency - 該 key 的預設點差 →
key_default - 平台預設 →
platform
同幣別貨幣對(例如 USD → USD)沒有發生兌換,不加點差,markup_source 為 none。
方向與取整都跟著 side 走,結果始終對你有利。 收款方:raw_rate × (1 + markup_bps/10000),金額無條件進位;付款方:raw_rate × (1 - markup_bps/10000),金額無條件捨去。
算例(數字僅為示例,並非即時行情;為方便比較,假設兩種情況選出的匯率都是 7.8000):一筆 1,000 美元的訂單,以港幣結算,點差 150 基點(1.5%)。
| 情境 | 不加點差 | 點差 150 基點 | 差額 |
|---|---|---|---|
你在收款(strategy=max) |
匯率 7.8000,客戶付 HK$7,800.00 | 匯率 7.9170,客戶付 HK$7,917.00 | 多收 HK$117.00 |
你在付款(strategy=min) |
匯率 7.8000,你付 HK$7,800.00 | 匯率 7.6830,你付 HK$7,683.00 | 少付 HK$117.00 |
先預覽再儲存。 在控制台設定點差時有效果預覽:調整數值時即時顯示客戶多付多少、你少付多少。
揭露。 在對加價有揭露要求的地區(例如歐盟面向消費者的支付),請向你的客戶揭露加價。
報價單鎖價
報價單把你展示給客戶的價格凍結到過期為止,展示與付款之間的匯率波動不會造成金額對不上。
POST /v1/quotes在建立時鎖定最終匯率rate、當時生效的點差markup_bps與結算金額payable- 之後在控制台修改這把 key 的點差,不會改變已發出的報價單
- 報價單在
ttl_seconds內有效(目前為 900 秒,即 15 分鐘)。請從回應讀取,不要寫死 - 保存
quote_id,客戶付款時以GET /v1/quotes/{quote_id}取回;超過expires_at會回傳 404,此時應重新建立報價單
網站示範
首頁上的線上示範僅供體驗,不是可以串接的 API:
- 資料延遲 1 小時:使用各資料來源 1 小時前的最新快照計算,並在結果旁標示資料時間
- 每次請求都經過無感的人機驗證(Cloudflare Turnstile)
- 使用平台預設點差,依網段與全站限流,尖峰時段可能顯示忙碌
- 不接受 API key,不計量,不占用任何帳號的配額
需要即時資料請在控制台免費建立 API key。
API 參考
驗證
所有 /v1 端點都必須帶 API key,沒有匿名存取。
| 請求標頭 | 範例 |
|---|---|
X-API-Key |
X-API-Key: <你的 key> |
Authorization |
Authorization: Bearer <你的 key> |
- 任選其一;兩者都帶時以
X-API-Key為準 - 在控制台建立與撤銷 key。需先完成電子郵件驗證,每個帳號最多同時持有 10 把有效 key。明文只顯示一次
- 撤銷後的 key 立即失效(HTTP 401
invalid_api_key) - 請從你的伺服器端呼叫。
/v1回應不帶 CORS 標頭;嵌在網頁或手機 App 裡的 key 任何人都能取走 GET /health與GET /openapi.json不需要 key
通用慣例
| 慣例 | 說明 |
|---|---|
| 匯率與金額一律為字串 | 不是 JSON number。JSON 的 number 是 IEEE 754 雙精度浮點數,0.05117904 這類值解析後會失去精度,導致金額算錯。請用 Decimal(Python)/ BigDecimal(Java)/ decimal.js(JS)解析。匯率固定 8 位小數 |
| 時間 | 一律為 ISO 8601 UTC 字串,例如 2026-09-14T10:38:01Z。需要做運算的地方另外提供 *_unix(Unix 秒,浮點數) |
| 百分比 | 字串,單位是 %(不是小數)。"0.1791" 表示 0.1791%,不是 17.91% |
| 貨幣代碼 | ISO 4217。請求中不區分大小寫,回應中一律大寫。見上文「支援的幣別」 |
| base / quote | base = 標價幣別,quote = 結算幣別(收款時是客戶付款的幣別,付款時是你付出的幣別)。匯率含義恆為「1 單位 base 可兌換多少 quote」 |
| 快取與 Cookie | 匯率回應帶 Cache-Control: no-store。API 從不設定 Cookie |
速率限制與每月配額
每個方案有一個速率限制(穩定速率加短時突發)與一個每月請求配額,公布於定價頁。
- 兩者都依帳號計算,不依 key。 同一帳號下的所有 API key 共用同一個速率限制與同一份每月配額,多建 key 不會提高任何一項。
X-Quota-*回應標頭顯示的是整個帳號的合計 - 每月配額於每個日曆月開始時(UTC)重置
- 通過驗證與限額檢查的請求,無論結果如何都計入配額 —— 包括 400、404、422、503。被 401、403、429 拒絕的請求不計入
- 對
/v1端點發出的HEAD請求與GET完全相同地處理(完整執行匯率計算),因此同樣計入配額與速率限制 - 不存在的路徑回傳 404
not_found,不計量
所有 /v1 回應(包括錯誤回應)都帶以下標頭:
| 標頭 | 含義 |
|---|---|
X-RateLimit-Limit |
最大突發量:可連續送出多少個請求 |
X-RateLimit-Remaining |
此刻不必等待還能送出多少個請求 |
X-RateLimit-Reset |
下一個請求名額可用的 Unix 時間(秒) |
X-Quota-Limit |
帳號的每月配額。0 表示不限 |
X-Quota-Used |
帳號本月已用請求數,含本次 |
X-Quota-Remaining |
本月剩餘請求數。X-Quota-Limit 為 0(不限)時恆為 0,請先看上限 |
X-Request-Id |
本次請求的 ID。聯絡支援時請附上 |
Retry-After |
需等待的秒數。只隨 429 rate_limited 回傳 |
請求無法歸屬到某個帳號時(缺少或無效的 key、帳號停用或電子郵件未驗證、請求本文超限、內部錯誤),速率與配額標頭提供的是與任何帳號無關的中性預設值。
觸及限額時
| 回應 | 含義 | 怎麼辦 |
|---|---|---|
429 rate_limited |
短時間內請求過多 | 等待 Retry-After 秒(回應本文也有 retry_after)後重試 |
429 quota_exceeded |
帳號本月配額已用完。硬性阻斷:不做超額計費,不帶 Retry-After |
不要重試。升級方案(upgrade_url 為定價頁的絕對位址)或等下個月。回應本文帶 used 與 quota |
請求處理順序
請求依以下順序檢查,第一個未通過的檢查決定回應:
- 請求本文大小:超過 16 KiB → 413
payload_too_large - 缺少 API key → 401
api_key_required;key 無效或已撤銷 → 401invalid_api_key - 帳號已停用 → 403
account_disabled;電子郵件未驗證 → 403email_not_verified - 速率限制 → 429
rate_limited;每月配額 → 429quota_exceeded - 參數 → 400
bad_request/ 400unsupported_currency/ 422currency_not_available(此時已計入配額) - 定價 → 有效來源不足 503
no_rate;資料儲存暫時無法連線 503storage_unavailable
GET /v1/rate
取得單一貨幣對的最終匯率,並附上全部資料來源的明細。
查詢參數
| 參數 | 必填 | 說明 |
|---|---|---|
base |
是 | 標價幣別。別名 from |
quote |
是 | 結算幣別。別名 to |
strategy |
否 | 匯率站在哪一邊:max(預設,收款方)/ min(付款方)/ median(中立)。不區分大小寫 |
同幣別貨幣對(例如 base=USD"e=USD)回傳匯率 1.00000000,chosen_provider 與 anchor_tier 為 identity。
回應:頂層欄位
| 欄位 | 型別 | 說明 |
|---|---|---|
base |
string | 標價幣別 |
quote |
string | 結算幣別 |
rate |
string | 最終匯率,計算金額就用它。收款方(side=charge)為 raw_rate × (1 + markup_bps/10000),付款方(side=pay)為 raw_rate × (1 - markup_bps/10000)。markup_bps 為 0 時等於 raw_rate |
raw_rate |
string | 套用點差前的匯率。依 strategy 在各來源中選出;觸及 cap_rate / floor_rate 時已被鉗制 |
mid_rate |
string | 有效來源的中位數,約等於市場中間價。可用來衡量你比市場高出多少 |
low_rate |
string | 有效來源中的最低匯率。strategy=min 且未觸及保底線時等於 raw_rate |
high_rate |
string | 有效來源中的最高匯率。strategy=max 且未觸及封頂線時等於 raw_rate |
markup_bps |
int | 本次實際套用的點差,單位為基點(100 基點 = 1%)。同幣別貨幣對恆為 0 |
markup_source |
string | 點差來源:key_currency(該 key 對此幣別的個別設定)/ key_default(該 key 的預設點差)/ platform(平台預設)/ none(同幣別貨幣對,不加點差) |
strategy |
string | 本次使用的選價策略:max / median / min |
side |
string | 本次站在哪一邊:charge(收款方;max 與 median)/ pay(付款方;min)。點差方向與取整方向跟隨它 |
chosen_provider |
string | 最終匯率來自哪個來源,匿名代號,例如 source_a。同幣別貨幣對為 identity |
source_count |
int | 參與定價的有效來源數量(不含被剔除者) |
spread_vs_mid_pct |
string | 最終匯率相對 mid_rate 的偏離,單位 %,4 位小數。收款時通常為正,付款時通常為負 |
anchor_rate |
string | 新鮮度基準。剔除異常值與封頂/保底都以它為準;取最新那一級的中位數 |
anchor_tier |
string | 基準來自哪一級:realtime / hourly / daily / all / identity。退到 daily 或 all 表示新鮮來源都暫時無法使用,報價可能偏離市場 |
anchor_notes |
string[] | 較新的級別為何未被採用為基準,英文說明。正常情況下為空陣列 |
cap_rate |
string | null | 封頂線:anchor_rate 加上固定幅度。raw_rate 不會超過它。同幣別貨幣對為 null |
capped |
bool | true 表示選出的匯率超過封頂線、被壓了回來。代表市場在變動而較慢的來源還沒跟上,值得告警 |
floor_rate |
string | null | 保底線:anchor_rate 減去同樣的幅度。raw_rate 不會低於它。同幣別貨幣對為 null |
floored |
bool | true 表示選出的匯率低於保底線、被拉了回來。多見於 strategy=min |
sources |
object[] | 全部資料來源明細,含被剔除的來源。見下表 |
generated_at |
string | 本次回應產生時間(ISO 8601 UTC) |
generated_at_unix |
float | 同上,Unix 秒 |
回應:sources[] 每一項
| 欄位 | 型別 | 說明 |
|---|---|---|
provider |
string | 穩定的匿名來源代號,例如 source_a |
label |
string | 顯示名稱,例如 Source A |
data_freq |
string | null | 該來源自身資料的更新頻率:realtime / hourly / daily |
rate |
string | null | 該來源給出的 base→quote 匯率。null 表示該來源未涵蓋此貨幣對 |
vs_anchor_pct |
string | null | 該來源相對 anchor_rate 的偏離,單位 %(正數表示較高) |
fetched_at |
string | 我們擷取它的時間(ISO 8601 UTC) |
age_seconds |
float | 距那次擷取過了多少秒 |
source_time |
string | null | 該來源自稱的資料時間。null 表示該來源不提供 |
used |
bool | 是否參與本次定價 |
chosen |
bool | 是否就是被選中的那個來源 |
excluded_code |
string | null | 機器可讀的剔除原因;參與定價時為 null。監控請比對它 |
excluded_reason |
string | null | 給人看的英文剔除原因;參與定價時為 null。文案可能調整,請勿解析 |
excluded_code 的取值
excluded_code |
excluded_reason 範例 |
含義 | 怎麼辦 |
|---|---|---|---|
missing_currency |
Source does not cover this currency pair |
該來源未涵蓋此貨幣對 | 正常,其他來源會補上 |
snapshot_stale |
Snapshot is stale (9000s > 7200s) |
太久沒有從該來源擷取到新資料 | 其他來源會補上;持續出現可查看狀態頁 |
deviates_from_anchor |
Deviates 12.5% from the realtime tier anchor, beyond +/-5%; treated as a data fault |
該來源數值離基準太遠 | 該來源資料很可能損壞,你這邊無需處理 |
GET /v1/rates
一次取得多個貨幣對的匯率表。每列是 GET /v1/rate 的精簡版,不含 sources 明細。
查詢參數
| 參數 | 必填 | 說明 |
|---|---|---|
base |
否 | 以逗號分隔的標價幣別,例如 USD,EUR。空項與重複項會被忽略 |
quote |
否 | 以逗號分隔的結算幣別,例如 JPY,HKD |
省略參數時使用服務的預設幣別網格;若你的串接依賴確切的列,請明確傳入兩個參數。
清單中有無法辨識的代碼時整個請求回傳 400 unsupported_currency;有暫時無法提供即時資料的幣別時回傳 422 currency_not_available。先整體檢查 base 清單,再檢查 quote:同一清單內無法辨識的代碼優先於暫時無法提供即時資料的幣別報錯,但 base 的問題總是先報,因此 base 含暫時無法提供即時資料的幣別、同時 quote=ZZZ 時回傳 422。
各列使用平台預設點差,不使用你這把 key 的點差。 需要套用你自己的點差時,請用
GET /v1/rate或GET /v1/convert。
回應
| 欄位 | 型別 | 說明 |
|---|---|---|
rows |
object[] | 每個 base × quote 組合一列 |
generated_at / generated_at_unix |
string / float | 產生時間 |
rows[] 每一項
| 欄位 | 型別 | 說明 |
|---|---|---|
base / quote |
string | 貨幣對 |
final_rate |
string | 依平台預設點差計算的最終匯率 |
raw_rate |
string | 套用點差前 |
mid_rate |
string | 各來源中位數 |
chosen_provider |
string | 被選中的來源(匿名代號) |
source_count |
int | 有效來源數量 |
markup_bps |
int | 套用的點差(平台預設) |
spread_pct |
string | 相對中間價的溢價,單位 %,3 位小數 |
anchor_tier |
string | 基準級別 |
capped |
bool | 是否觸及封頂線 |
error |
string | null | 不為 null 時該列沒有匯率:只有 base、quote、error 三個欄位。典型原因是該貨幣對有效來源不足。使用每一列之前務必判斷是否為 null |
GET /v1/convert
把標價幣別的金額換算成結算金額。金額取整到幣別的最小單位(JPY 到 1;USD、EUR、HKD、CNY 到 0.01),取整方向跟隨 side:收款無條件進位、付款無條件捨去,零頭始終對你有利。
查詢參數
| 參數 | 必填 | 說明 |
|---|---|---|
base / quote |
是 | 同 GET /v1/rate,含別名 from / to |
amount |
是 | 標價幣別金額,十進位字串,必須 > 0。換算結果(payable、mid_payable)依結算幣別最小單位取整後,連同小數位最多 28 位,超出時回傳 400 bad_request |
strategy |
否 | 同 GET /v1/rate |
回應
| 欄位 | 型別 | 說明 |
|---|---|---|
base / quote |
string | 貨幣對 |
amount |
string | 你傳入的金額,十進位字串 |
payable |
string | 結算金額。收款方(side=charge)是客戶應付金額,無條件進位;付款方(side=pay)是你應付出的金額,無條件捨去 |
rate |
string | 使用的最終匯率 |
mid_rate |
string | 市場中間價 |
mid_payable |
string | 以中間價計算的金額(四捨五入),供比較 |
gain_vs_mid |
string | 對你有利的差額,越大越好。收款方:payable - mid_payable(多收的);付款方:mid_payable - payable(少付的) |
markup_bps |
int | 套用的點差 |
markup_source |
string | 點差來源,同 GET /v1/rate |
side |
string | charge / pay,同 GET /v1/rate |
chosen_provider |
string | 匯率來自哪個來源(匿名代號) |
source_count |
int | 有效來源數量 |
anchor_tier |
string | 基準級別 |
capped |
bool | 是否觸及封頂線 |
floored |
bool | 是否觸及保底線 |
GET /v1/convert只做換算,不鎖價。實際下單請用POST /v1/quotes。
POST /v1/quotes
建立鎖價報價單:匯率、點差與 payable 在 ttl_seconds 內保持不變,結算以 payable 為準。
請求本文(JSON 物件,Content-Type: application/json,不超過 16 KiB)
| 欄位 | 必填 | 說明 |
|---|---|---|
base / quote |
是 | 貨幣對。別名 from / to |
amount |
是 | 標價幣別金額,必須 > 0。建議傳十進位字串,也接受 JSON number |
reference |
否 | 你自己的訂單編號(最多 128 個字元),原樣保存並回傳,方便對帳 |
strategy |
否 | 匯率站在哪一邊,同 GET /v1/rate |
請求本文不是合法 JSON、不是 JSON 物件或欄位型別不符時回傳 400 bad_request。
回應(HTTP 201)
| 欄位 | 型別 | 說明 |
|---|---|---|
quote_id |
string | 報價單 ID(32 位小寫十六進位)。請保存,供後續查詢與對帳 |
reference |
string | null | 原樣回傳你傳入的訂單編號 |
base / quote |
string | 貨幣對 |
amount |
string | 標價幣別金額 |
payable |
string | 結算金額,即鎖定的值。過期前不會變動。取整方向跟隨 side |
rate |
string | 鎖定的最終匯率 |
raw_rate |
string | 套用點差前的匯率 |
mid_rate |
string | 下單時的市場中間價,方便對帳 |
markup_bps |
int | 建立時鎖定的點差。之後在控制台修改點差不影響這張報價單 |
strategy |
string | 選價策略 |
side |
string | charge / pay,同 GET /v1/rate |
chosen_provider |
string | 匯率來自哪個來源(匿名代號)—— 爭議或對帳時的憑據 |
source_count |
int | 當時的有效來源數量 |
created_at / created_at_unix |
string / float | 建立時間 |
expires_at / expires_at_unix |
string / float | 過期時間。過期後以該 ID 查詢回傳 404 |
ttl_seconds |
int | 鎖價時長(秒) |
報價單無法保存時回傳 503 storage_unavailable,此時報價單不存在,請重試。
GET /v1/quotes/{quote_id}
取回報價單。欄位與建立時回傳的完全相同,另多一個:
| 欄位 | 型別 | 說明 |
|---|---|---|
expired |
bool | 是否已過期。報價單一過期就會被刪除,通常你會直接得到 404;只有在刪除前的極短時間內這個欄位才可能為 true |
quote_id不是 32 位小寫十六進位,或報價單不存在、已過期 → 404not_found- 503
storage_unavailable表示此刻無法查詢,不代表報價單已過期。請重試
GET /v1/sources
目前為你提供匯率的資料來源有哪些、各自有多新鮮。用來判斷某個匯率可以信任到什麼程度。
回應
| 欄位 | 型別 | 說明 |
|---|---|---|
sources |
object[] | 目前啟用的資料來源 |
source_count |
int | 資料來源數量 |
last_poll_at |
string | null | 最近一次擷取時間(ISO 8601 UTC) |
sources[] 每一項
| 欄位 | 型別 | 說明 |
|---|---|---|
provider |
string | 匿名來源代號,與 GET /v1/rate 的 sources[].provider 對應 |
label |
string | 資料來源顯示名稱 |
data_freq |
string | 該來源自身資料的更新頻率:realtime / hourly / daily |
last_fetch_at |
string | null | 我們最近一次從該來源擷取的時間 |
last_fetch_age |
float | null | 距最近一次擷取過了多少秒 |
source_time |
string | null | 該來源自稱的資料時間。null 表示該來源不提供 |
source_age_seconds |
float | null | 該來源資料的年齡(秒) |
currencies |
int | 該來源目前涵蓋多少個支援的幣別 |
這兩個時間含義完全不同。
last_fetch_at是我們拉取資料的時間,所以總是很新;source_time是資料來源自己聲稱的資料時間。每日更新的來源通常落後 12–36 小時, 個別每日來源在週末會超過 80 小時 —— 這是正常的。 只看last_fetch_at判斷新鮮度會嚴重誤判。
GET /health
服務健康檢查,不需要 API key。供你的監控或負載平衡器使用。
| 欄位 | 型別 | 含義 |
|---|---|---|
status |
string | ok / degraded。只反映「此刻能不能報價」 |
sources_healthy |
int | 目前有新鮮可用資料的來源數量 |
last_updated_at |
string | null | 最近一次擷取到來源資料的時間(ISO 8601 UTC) |
HTTP 狀態:ok 時 200,degraded 時 503。
此端點刻意只回傳一個健康訊號,不透露內部擷取狀態與上游錯誤細節。 需要逐一來源的新鮮度請用
GET /v1/sources,或查看狀態頁。
GET /openapi.json
上述全部端點的 OpenAPI 3.1 文件,位址為 https://api.crestrate.com/openapi.json。不需要 API key,允許瀏覽器跨來源讀取,快取 5 分鐘。文件同時宣告兩種驗證方式(X-API-Key 與 Bearer),SDK 產生器可直接使用。
網站上的 https://crestrate.com/openapi.json 以 HTTP 302 重新導向到上述位址。工具中請直接填寫 API 位址。
錯誤回應
所有端點的錯誤格式一致:
| 欄位 | 型別 | 說明 |
|---|---|---|
error |
string | 機器可讀的錯誤碼。請依它比對,不要依 message |
message |
string | 給人看的英文說明,文案可能調整 |
currency |
string | 出錯的幣別代碼(unsupported_currency、currency_not_available) |
supported |
string[] | 提供即時資料的幣別(currency_not_available) |
retry_after |
number | 需等待的秒數(rate_limited) |
used / quota |
int | 本月已用請求數 / 每月配額(quota_exceeded) |
upgrade_url |
string | 定價頁的絕對位址(quota_exceeded) |
| HTTP | error |
含義 | 可以重試嗎 |
|---|---|---|---|
| 400 | bad_request |
參數缺漏或不合法:缺 base/quote、缺 amount、amount ≤ 0、不是數字或過大、未知 strategy、請求本文不是合法 JSON、reference 過長 |
否,先修正請求 |
| 400 | unsupported_currency |
無法辨識的幣別代碼。帶 currency |
否 |
| 401 | api_key_required |
沒有帶 API key | 否,請帶 X-API-Key 或 Authorization: Bearer |
| 401 | invalid_api_key |
key 無效或已撤銷 | 否 |
| 403 | account_disabled |
帳號已被停用,請聯絡支援 | 否 |
| 403 | email_not_verified |
帳號電子郵件尚未驗證 | 驗證後可以 |
| 404 | not_found |
報價單不存在或已過期;路徑不存在 | 否 |
| 413 | payload_too_large |
請求本文超過 16 KiB | 否 |
| 422 | currency_not_available |
該幣別暫時無法提供即時資料。帶 currency 與 supported |
開放前不行 |
| 429 | rate_limited |
超過速率限制。帶 Retry-After 標頭與 retry_after 欄位 |
可以,等 Retry-After 之後 |
| 429 | quota_exceeded |
每月配額已用完。帶 used、quota、upgrade_url |
否,升級或等下個月 |
| 500 | internal_error |
伺服器端非預期錯誤 | 可以,退避重試;持續發生請附 X-Request-Id 聯絡支援 |
| 503 | no_rate |
有效來源不足,無法給出可信的匯率。message 列出各來源被剔除的原因(僅含匿名代號) |
可以,稍後重試;期間使用你自己的備用匯率 |
| 503 | storage_unavailable |
服務暫時無法使用,未保存任何資料 | 可以,退避重試 |
範例:
{
"error": "currency_not_available",
"message": "Real-time data for GBP is temporarily unavailable. Supported: USD, JPY, EUR, HKD, CNY.",
"currency": "GBP",
"supported": ["USD", "JPY", "EUR", "HKD", "CNY"]
}
503 no_rate 是刻意的 —— 我們寧可不報價,也不給來源有疑慮的價格。呼叫方應稍後重試,或改用自己的備用匯率。不要當成 0 處理。
最佳實踐
用 strategy 選對邊。 向客戶收款用預設的 max,支付賣家或供應商用 min,median 只用於記帳。選錯了,選價、點差與取整就都在替對方著想。
用十進位型別解析匯率,永遠不要用浮點數。 所有匯率與金額都是 JSON 字串,正是為此。
以 IEEE-754 雙精度解析,0.05117904 會失去精度,合計金額會逐漸偏移。
請用 Decimal / BigDecimal / decimal.js / bcmath。
收款前一定先鎖價。 客戶看到價格與實際付款之間有時間差,匯率在這段時間內會變動。
POST /v1/quotes 把匯率、點差與金額凍結到 TTL 結束,並給你一個 quote_id 供之後對帳。
GET /v1/convert 只用於顯示與估算 —— 不要用它下單。
rate_limited 值得重試,quota_exceeded 不值得。 前者是暫時的,依 Retry-After 退避後再試。
後者在本日曆月內是硬性阻斷,而且帳號下所有 key 共同受限。請升級,或等下個月重置。
永遠不要把 503 no_rate 當成 0。 它的意思是「有效來源太少,我們不會給你一個站不住腳的價格」。
改用你自己的備用匯率,或暫停下單流程。不要乘以 0。
在你這邊先檢查幣別。 使用暫時無法提供即時資料之幣別的請求同樣計入配額;呼叫前請先對照支援清單。
在你這邊做快取。 匯率不會比我們最快的來源變得更快。快取 30–60 秒能大幅減少用量,精度幾乎不受影響。
留意 capped、floored 與 anchor_tier。 capped: true 或 floored: true 表示市場在變動而較慢的來源還沒跟上,我們把報價鉗回即時市場附近。
anchor_tier 退到 daily 或 all 表示最新的來源暫時無法使用 —— 匯率仍可使用,只是不如平時新鮮。
監控請比對 error 與 excluded_code,不要比對文案。 message 與 excluded_reason 是給人看的,措辭可能調整。
版本政策
目前為 v1,版本號是路徑的一部分(/v1)。我們會新增欄位而不另行通知,請做防禦性解析,忽略不認得的鍵。
刪除或改變現有欄位的用途、修改欄位型別、修改錯誤碼的含義或 HTTP 狀態,我們不會在少於 90 天通知期的情況下進行。 通知會寄送到近期有呼叫的每位客戶的帳號電子郵件。
支援
有疑問,或發現行為與文件不符?請寄信至 [email protected],並附上該請求的 X-Request-Id。