用 Node.js API 串接:TypeScript 使用 Narwhal API

用 Node.js 和 TypeScript 搭配 Narwhal,可以取得國定假日、發布日期、經濟數據、大宗商品現貨價格、匯率和預測市場賠率。直接用原生 fetch 加上你的 API 金鑰,再用 cron 或主機上的排程工作執行腳本。

你將完成的設定

Node.js 為呼叫 Narwhal REST API 並讀取 JSON 回應的腳本提供 JavaScript 執行環境。你會得到一個 ES 模組,帶有共用的請求輔助函式,以及對全部六個資料領域的呼叫。Narwhal 以一個帳號、一把 API 金鑰涵蓋所有資料 API,REST 與 MCP 共用該金鑰。這裡的腳本使用 REST,金鑰從環境變數讀取。

設定你的 API 金鑰

  1. 建立免費金鑰 在 註冊頁面 取得免費 API 金鑰。這個腳本中每個資料領域的請求都用同一把金鑰驗證。
  2. 把金鑰存入環境檔 把金鑰以 NARWHAL_API_KEY 為名放進 .env 檔。把 YOUR_KEY 換成你的金鑰;腳本透過 process.env.NARWHAL_API_KEY 讀取該值。
    環境檔
    NARWHAL_API_KEY=YOUR_KEY
  3. 使用 ES 模組和相符的 Node 版本 把腳本儲存為 pull.mjs。Node 18.17 及更新版本內建全域 fetch,因此 REST 呼叫不需要任何套件。用 node --env-file=.env pull.mjs 載入 .env 檔則需要 Node 20.6 或更新版本。

標頭是 Authorization: Bearer YOUR_KEY。在腳本中,標頭的值取自環境變數,基礎 URL 仍是 https://api.narwhalapi.com。每次呼叫都透過共用的輔助函式使用同一個標頭。

用程式碼取得資料

把這段程式碼儲存到 pull.mjs。get 輔助函式根據基礎 URL 和路徑建立 URL,附上傳入的查詢參數,並用 fetch 傳送 GET 請求。如果回應不成功,它會擲出包含狀態和回應文字的錯誤;否則回傳 JSON 回應,供呼叫端讀取。

輔助函式和各領域的呼叫放在同一個 ES 模組裡,並在發出請求之前先定義基礎 URL 和標頭。參數物件屬於每次呼叫:日曆呼叫提供國家和日期篩選條件,CPI 呼叫提供起始期間,FX 呼叫提供貨幣。

Node,六個領域
const API = "https://api.narwhalapi.com";
const headers = { Authorization: `Bearer ${process.env.NARWHAL_API_KEY}` };

async function get(path, params = {}) {
  const url = new URL(API + path);
  for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);
  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  return res.json();
}

const { holidays } = await get("/v1/calendars/holidays/USA/2026");
const { releases } = await get("/v1/economics/calendar", {
  countries: "USA",
  start_date: "2026-11-01",
  end_date: "2026-11-30",
  limit: 100,
});
const { observations } = await get("/v1/economics/USA/cpi/observations", {
  start: "2025-09",
});
const { price } = await get("/v1/commodities/spot/BRENT/USD");
const { rates } = await get("/v1/fx/rates/USD", { currencies: "EUR,IDR" });
const { meetings } = await get("/v1/predictions/policy-paths/federal-reserve");

console.log(holidays.length, holidays[0].name);
console.log(releases.length, observations.at(-1));
console.log(
  "Brent",
  price,
  Object.fromEntries(rates.map((rate) => [rate.currency, rate.rate])),
);
console.log(meetings[0].resolves_at.slice(0, 10), meetings[0].p_hold);

執行 node --env-file=.env pull.mjs 來載入金鑰並呼叫 API。各個呼叫會擷取輸出語句所用的回應欄位。對於匯率,腳本把回傳的貨幣和匯率項目轉成物件;對於預測回應,它讀取會議日期和維持不變機率。後面的各領域範例也使用同一個 get 輔助函式和標頭。

排定定時擷取

使用 cron 或主機上的排程工作。用 cron 時,命令裡要包含環境檔的路徑和 pull.mjs 的路徑,這樣排程執行的腳本才能透過 process.env.NARWHAL_API_KEY 取得金鑰。命令被排程執行時,--env-file 選項仍然需要 Node 20.6 或更新版本。

cron 項目
0 7 * * * node --env-file=/path/.env /path/pull.mjs

把 /path/.env 和 /path/pull.mjs 換成你自己檔案的路徑。有關排程請求的更多內容,請見排定每日資料擷取。

在 Node.js 中使用國定假日

請求 2026 年美國國定假日並讀取 holidays 陣列。每個假日都有 date 和 name;範例會列印陣列長度和第一個假日的名稱。截至 2026 年 10 月 24 日,回應包含 2026 年的 11 個美國國定假日。若要在自己的輸出中使用日期,讀取假日項目的 date。name 欄位提供與該日期對應的假日名稱。

讀取國定假日
const { holidays } = await get(
  "/v1/calendars/holidays/USA/2026"
);
console.log(holidays.length, holidays[0].name);

在 Node.js 中使用發布日期

請求 2026 年 11 月這段時間的美國經濟日曆並讀取 releases。每個項目都有 at、period、topic 和 status,因此可以把發布日期與主題和期間一起讀取。截至 2026 年 10 月 24 日,這個 2026 年 11 月的區間內有 31 次發布。日期篩選屬於日曆請求,而 period 欄位屬於每個發布項目。需要在輸出中使用主題和狀態時,從同一個項目讀取即可。

讀取發布日期
const { releases } = await get("/v1/economics/calendar", {
  countries: "USA", start_date: "2026-11-01", end_date: "2026-11-30", limit: 100
});
console.log(releases.length);

在 Node.js 中使用經濟數據

帶上 start 參數請求美國 CPI 觀測值並讀取 observations。每筆觀測值都有 period 和 value;範例讀取回傳陣列中的最後一項。截至 2026 年 10 月 24 日,2026-09 這一期的 CPI 數值為 336.940。Narwhal 的經濟數據還包括通膨、GDP 和殖利率。讀取觀測值時,請讓期間與數值一起保留,這樣輸出就能說明該數值屬於哪個 CPI 期間。請求的起始期間透過查詢參數傳入。

讀取 CPI 觀測值
const { observations } = await get(
  "/v1/economics/USA/cpi/observations", { start: "2025-09" }
);
console.log(observations.at(-1));

在 Node.js 中使用大宗商品現貨價格

請求以 USD 計價的 Brent,並讀取回應欄位 price。截至 2026 年 10 月 24 日,Brent 為每桶 116.8809 美元。現貨代碼例如有 XAU、XAG、XPT、XPD、XCU、BRENT 和 WTI。此範例在請求路徑中使用 BRENT 和 USD。這裡的程式碼從 JSON 回應中讀取單一 price 欄位。大宗商品代碼和貨幣是傳給共用請求輔助函式的 URL 的一部分。

讀取 Brent 現貨價格
const { price } = await get(
  "/v1/commodities/spot/BRENT/USD"
);
console.log("Brent", price);

在 Node.js 中使用匯率

以 USD 為基礎請求 EUR 和 IDR,並讀取 rates。每一項都有 currency 和 rate,小數形式的匯率是字串。截至 2026 年 10 月 24 日,USD/EUR 為 0.89342,USD/IDR 為 18107.8。範例把每種貨幣作為物件屬性,對應其回傳的匯率。所請求的貨幣是查詢參數,基礎貨幣則在路徑中。直接使用回傳的陣列時,請連同每個匯率一起讀取貨幣欄位。

讀取匯率
const { rates } = await get(
  "/v1/fx/rates/USD", { currencies: "EUR,IDR" }
);
console.log(Object.fromEntries(rates.map((rate) => [rate.currency, rate.rate])));

在 Node.js 中使用預測市場賠率

請求聯準會政策路徑並讀取 meetings。每場會議都有 resolves_at、p_cut、p_hold 和 p_hike。截至 2026 年 10 月 24 日,2026 年 10 月 28 日那場會議的維持不變機率為 0.9188。範例把第一個會議項目的日期與其維持不變機率一起列印。需要降息或升息機率時,使用會議項目中的 p_cut 或 p_hike。請讓 resolves_at 與機率一起保留,以標明它描述的是哪場會議。

讀取會議賠率
const { meetings } = await get(
  "/v1/predictions/policy-paths/federal-reserve"
);
console.log(meetings[0].resolves_at.slice(0, 10), meetings[0].p_hold);

需要 TypeScript 型別嗎?

只為你讀取的回應欄位加上型別即可。以 FX 範例來說,回應的結構是 { rates: { currency: string; rate: string }[] }。小數值是字串,所以在 TypeScript 結構中把 rate 宣告為 string。

為什麼 await 在頂層?

ES 模組允許使用頂層 await,範例正是靠它來等待每個 get 呼叫。請使用這裡的 .mjs 副檔名,或為 JavaScript ES 模組設定 "type": "module"。

發布於 。

後續步驟