快速入門
從零到第一次成功呼叫,通常不到兩分鐘。
基礎位址: https://api.crestrate.com/v1
取得 API key
註冊後在控制台建立。免費方案每月 1,000 次,無需信用卡。 明文只顯示一次,請當場存進您的密鑰管理工具。
查詢匯率
base 是商品標價幣別,quote 是客戶支付幣別。回傳的 rate 就是「1 單位 base 換多少 quote」,可直接用來計算金額。
所有 /v1 請求都必須透過 X-API-Key 或 Authorization: Bearer 附上 key,否則回傳 401 api_key_required。
curl -H "X-API-Key: $CR_API_KEY" \
"https://api.crestrate.com/v1/rate?base=JPY"e=HKD"所有匯率和金額都是字串,不是 JSON number。 JSON 的 number 是 IEEE 754 雙精度,
0.05117904 這類值解析後會失去精度、金額算錯。請用 Decimal / BigDecimal / decimal.js / bcmath 解析。下單時鎖定價格
客戶從看到價格到實際付款之間有時間差,匯率會變動。用 POST /v1/quotes 鎖定報價,取得的 payable 在有效期限內不變,對帳才不會亂。
curl -X POST "https://api.crestrate.com/v1/quotes" \
-H "X-API-Key: $CR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"base":"JPY","quote":"HKD","amount":"10000","reference":"ORDER-8823"}'
# → {"quote_id":"4ac0…","payable":"524.15","rate":"0.05241460",
# "expires_at":"2026-09-14T12:53:01Z","ttl_seconds":900, …}處理速率限制與配額
每個回應都帶 6 個標頭,用戶端應據此退避,而不是硬重試。
| 回應標頭 | 含義 |
|---|---|
X-RateLimit-Limit | 權杖桶容量(瞬間突發上限) |
X-RateLimit-Remaining | 目前剩餘權杖 |
X-RateLimit-Reset | 下一枚權杖到達的時刻(epoch 秒),依此安排下次呼叫 |
X-Quota-Limit | 本月配額 |
X-Quota-Used | 本月已用 |
X-Quota-Remaining | 本月剩餘 |
429 quota_exceeded 是硬性阻斷,要到下個自然月(UTC)或升級後才恢復,重試沒有用;只有 429 rate_limited 值得依 Retry-After 等待後重試。
async function getRate(base, quote, attempt = 0) {
const res = await fetch(
`https://api.crestrate.com/v1/rate?base=${base}"e=${quote}`,
{ headers: { "X-API-Key": process.env.CR_API_KEY } }
);
if (res.status === 429) {
const body = await res.json();
// quota_exceeded is a hard stop: retrying won't help, upgrade or wait for next month
if (body.error === "quota_exceeded") {
throw new Error(`Monthly quota exhausted: ${body.used}/${body.quota}`);
}
// only rate_limited is worth retrying, after Retry-After
if (attempt < 3) {
const wait = Number(res.headers.get("Retry-After") || 1);
await new Promise(r => setTimeout(r, wait * 1000));
return getRate(base, quote, attempt + 1);
}
throw new Error("rate limited");
}
// 503 no_rate: not enough valid sources. We return no price rather than a doubtful one.
// Fall back to your own rate; never treat it as 0.
if (res.status === 503) throw new Error("no reliable rate available");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}別把 503 當成 0。 有效資料來源不足時,API 回傳
503 no_rate 而不是硬湊一個價格——這是刻意設計。呼叫方應退回自己的備援匯率或暫停下單,絕不能當成匯率為 0。