Node.jsでリアルタイムの金価格を取得するには、標準のfetchでapi.goldprice.dev/v1/spot/XAU-USD-SPOTにGETリクエストを送ります。APIキーはX-API-Keyヘッダーに指定します。HTTPライブラリは不要です。応答をMapに60秒間キャッシュし、価格の計算にはdecimal.jsを使います。無料プランは月5,000回までで、クレジットカードは不要です。2026年7月にNode 22 LTSで動作確認済みです。
goldprice.devのAPIキーを取得する
goldprice.dev/onboardingで無料アカウントを作成します。メール認証後、ダッシュボードにga_live_で始まるキーが表示されます。環境変数に設定します。
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_here無料プランでは月5,000回まで呼び出せます。金のスポット価格は31通貨に対応しています。クレジットカードは不要です。
decimal.jsをインストールする
Node 18+には標準でfetchがあるため、HTTPクライアントは不要です。必要な依存パッケージはdecimal.jsだけです。JavaScriptのNumberで生じる誤差を避け、価格を正確に計算できます。次のコマンドでインストールします。
npm install decimal.jsgoldpriceクライアントを作成する
次のコードをgoldprice.mjsとして保存します。spot()は銘柄ごとにMapへ60秒間キャッシュし、429時は指数バックオフで最大3回再試行します。価格はDecimalで返します。任意項目の売値と買値は有料プランのみで、値がなければnullになります。
// node: goldprice.mjs// curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTimport Decimal from "decimal.js";const API_BASE = "https://api.goldprice.dev";const API_KEY = process.env.GOLDPRICE_API_KEY;if (!API_KEY) { throw new Error("GOLDPRICE_API_KEY not set");}const TTL_MS = 60_000;const cache = new Map();/** Fetch live spot price. Cached 60s per symbol, retries 3x on 429. */export async function spot(symbol = "XAU-USD-SPOT") { const cached = cache.get(symbol); if (cached && cached.expiresAt > Date.now()) { return cached.data; } let lastErr; for (let attempt = 0; attempt < 3; attempt++) { const res = await fetch(`${API_BASE}/v1/spot/${symbol}`, { headers: { "X-API-Key": API_KEY }, signal: AbortSignal.timeout(5000), }); if (res.status === 429) { lastErr = new Error("goldprice: 429 rate limited"); const backoffMs = 2 ** attempt * 1000; // 1s, 2s, 4s await new Promise((resolve) => setTimeout(resolve, backoffMs)); continue; } if (!res.ok) { throw new Error(`goldprice: unexpected status ${res.status}`); } const raw = await res.json(); const data = { symbol: raw.symbol, quoteCurrency: raw.quote_currency, price: new Decimal(raw.price), bid: raw.bid == null ? null : new Decimal(raw.bid), ask: raw.ask == null ? null : new Decimal(raw.ask), isStale: raw.is_stale, computedAt: raw.computed_at, }; cache.set(symbol, { data, expiresAt: Date.now() + TTL_MS }); return data; } throw lastErr;}実行する
モジュールをインポートしてspot()を呼び出します。初回はAPIにアクセスし、60秒以内の呼び出しは通信せず、キャッシュしたDecimalを返します。キャッシュはプロセス内にあるため、再起動すると消えます。複数のプロセスで共有する場合はRedisを使います。
import { spot } from "./goldprice.mjs";const r = await spot("XAU-USD-SPOT");console.log(`${r.symbol}-${r.quoteCurrency}: ${r.price} (computed ${r.computedAt})`);// XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)通貨や金属を変更する
銘柄の形式はMETAL-CURRENCY-SPOTです。対応する31通貨の銘柄をspot()に渡します。Mapでは銘柄ごとにキャッシュします。5銘柄を60秒間隔で取得するダッシュボードでは、キャッシュがなければ毎分5回、あれば0回のAPI呼び出しになります。
// USD spot, defaultawait spot("XAU-USD-SPOT");await spot("XAU-INR-SPOT");await spot("XAU-EUR-SPOT");// Silver in USDawait spot("XAG-USD-SPOT");出力例
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4012.75", "is_stale": false, "computed_at": "2026-10-23T07:00:18.221118+00:00"}標準出力には、銘柄、表示通貨、decimal.jsのDecimal型の価格、ISO 8601形式のcomputedAtタイムスタンプが同じ行に表示されます。後続のコードでは、spot()が返す通常のオブジェクトを使います。
よくあるエラー
| コード | 症状 | 対処方法 |
|---|---|---|
| 401 | 初回の呼び出しでgoldprice: unexpected status 401が出る | APIキーが未設定か無効です。echo $GOLDPRICE_API_KEYで設定を確認します。空ならダッシュボードのキーを環境変数に再設定します。環境変数が空の場合はインポート時に例外が発生するため、リクエスト処理の途中まで問題を見逃さずに済みます。 |
| 429 | 待機を挟んで3回再試行しても429が返り、spot()が失敗する | 分あたりの上限に達しています。一定間隔の取得には60秒キャッシュが有効です。異なる銘柄のリクエストが同時に集中する場合は、呼び出す時刻をずらします。大量の呼び出しを継続する場合は、/pricingで有料プランを確認してください。 |
| N/A | 価格は正しく見えるが、計算を繰り返すと少しずつずれる | JavaScriptのNumberはIEEE-754浮動小数点数で、0.1 + 0.2 === 0.30000000000000004となります。金価格は小数点以下2桁のため、数千件をNumberで合計するとベーシスポイント単位の誤差が生じます。計算中はdecimal.jsのDecimalを保ち、表示やシリアライズの直前にだけ.toString()や.toNumber()を使います。 |
活用方法
- キャッシュをプロセス間で共有します。
MapをRedisのキャッシュに置き換えると、複数のワーカーが取得済みの価格を使えます /v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...を呼ぶbars()を追加し、時系列データをバックテストに使います- ExpressやFastifyのルートからクライアントを呼び、Node以外のサービス向けに内部公開します
- キャッシュがない同じ銘柄への同時リクエストをまとめ、呼び出しが集中しても取得を重複させないようにします
- キャッシュのヒット率、p50/p95の応答時間、429の再試行回数をPrometheusの指標として公開します