快速开始
从零到第一次成功调用,通常不到两分钟。
基础地址: 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。 有效数据源不足时,接口返回
503 no_rate 而不是硬凑一个价——这是刻意设计。调用方应回落到自己的兜底汇率或暂停下单,绝不能当成汇率为 0。