クイックスタート
ゼロから最初の呼び出し成功まで、通常 2 分もかかりません。
ベース URL: https://api.crestrate.com/v1
API キーを取得する
登録後、ダッシュボードでキーを作成します。無料プランは月 1,000 リクエストまで、クレジットカードは不要です。 キーの全文は一度しか表示されません。すぐにシークレット管理ツールに保存してください。
レートを照会する
base は商品の価格通貨、quote はお客様の支払通貨です。返される rate は「base 1 単位が quote でいくらか」を表し、そのまま金額計算に使えます。
/v1 へのリクエストにはすべて X-API-Key または Authorization: Bearer でキーが必要です。キーがない場合は 401 api_key_required が返ります。
curl -H "X-API-Key: $CR_API_KEY" \
"https://api.crestrate.com/v1/rate?base=JPY"e=HKD"レートと金額は JSON の数値ではなく文字列です。 JSON の数値は 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 | 次のトークンが補充される時刻(エポック秒)。次の呼び出しはこれに合わせてください |
X-Quota-Limit | 月間クォータ |
X-Quota-Used | 今月の使用量 |
X-Quota-Remaining | 今月の残り |
429 quota_exceeded は翌暦月(UTC)かアップグレードまで解除されないため、再試行しても意味がありません。再試行すべきなのは Retry-After 後の 429 rate_limited だけです。
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 をゼロとして扱わないでください。 有効なソースが足りないとき、API は無理にレートを作らず
503 no_rate を返します。これは意図的な設計です。自前のフォールバックレートを使うか注文を一時停止し、決してレート 0 として扱わないでください。