スプレッドシート API で Narwhal を Google Sheets に連携する

Narwhal API を使うと、祝日、発表日、経済データ、コモディティのスポット価格、為替レート、予測市場の確率を Google スプレッドシートに取り込めます。Apps Script でデータを別々のタブに書き込み、時間主導型トリガーを追加すれば、スケジュールどおりに更新できます。

セットアップする内容

Apps Script は、UrlFetchApp を通じてスプレッドシートを API に接続します。データ領域ごとにタブができ、同じAPIキーでそれらを埋める pullAll 関数も手に入ります。キーはスクリプトプロパティに保存され、スクリプトはリクエストのたびにそれを読みます。REST と MCP は、各データ API でこのキーを共有します。ベース URL は https://api.narwhalapi.com で、どのデータ呼び出しも GET を使います。

APIキーを設定

  1. 無料キーを作成する 無料の Narwhal APIキーを取得します。エディターで追加するスクリプトプロパティ用にキーを手元に置いておき、スプレッドシートのセルには絶対に入れないでください。
  2. Apps Script を開く Google スプレッドシートで [拡張機能] メニューを開き、[Apps Script] を選びます。ここでスクリプトを追加し、キーを使うためのアクセスも設定します。
  3. キーをスクリプトプロパティに保存する [プロジェクトの設定] で、NARWHAL_API_KEY という名前のスクリプトプロパティを追加し、値にキーを設定します。スクリプトは PropertiesService.getScriptProperties() でこれを読み、Authorization ヘッダーに Bearer YOUR_KEY として付けて送ります。

Apps Script でデータを取得する

  1. データ用のタブを作成する Holidays、Releases、CPI、Brent、FX、Fed という名前のタブを作成します。スクリプトがこれらの名前でレスポンスの書き込み先を探すため、名前は表記どおりにしてください。
  2. スクリプトを追加する このコードを Apps Script に貼り付けます。共通の pull ヘルパーは、各呼び出しで指定されたレスポンスのフィールドを読み、対応するタブに行を書き込みます。Brent は価格がリストの外にあるため、レスポンスのオブジェクトをそのまま使います。
    Apps Script、6 つの領域
    const API = "https://api.narwhalapi.com";
    
    function pull(sheetName, path, listKey) {
      const key = PropertiesService.getScriptProperties().getProperty("NARWHAL_API_KEY");
      const res = UrlFetchApp.fetch(API + path, {
        headers: { Authorization: "Bearer " + key },
      });
      const body = JSON.parse(res.getContentText());
      const rows = listKey ? body[listKey] : [body];
      if (!rows || rows.length === 0) return; // an empty list writes nothing
      const columns = [];
      rows.forEach((row) =>
        Object.keys(row).forEach((name) => {
          // every row, so a null first value cannot hide a column
          if (
            !columns.includes(name) &&
            (row[name] === null || typeof row[name] !== "object")
          )
            columns.push(name);
        }),
      );
      const values = [columns].concat(
        rows.map((row) =>
          columns.map((name) =>
            row[name] === undefined || row[name] === null ? "" : row[name],
          ),
        ),
      );
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
      sheet.clear();
      // Text columns (dates, periods like 2026-09) stay plain text so Sheets does not
      // turn them into dates.
      // Decimal strings such as "1.0823" stay numbers.
      columns.forEach((name, index) => {
        const sample = rows.find(
          (row) => typeof row[name] === "string" && row[name] !== "",
        );
        if (sample && !/^-?\d+(\.\d+)?$/.test(sample[name]))
          sheet.getRange(1, index + 1, values.length, 1).setNumberFormat("@");
      });
      sheet.getRange(1, 1, values.length, columns.length).setValues(values);
    }
    
    function pullAll() {
      pull("Holidays", "/v1/calendars/holidays/USA/2026", "holidays");
      pull(
        "Releases",
        "/v1/economics/calendar?countries=USA&start_date=2026-11-01" +
          "&end_date=2026-11-30&limit=100",
        "releases",
      );
      pull("CPI", "/v1/economics/USA/cpi/observations?start=2025-09", "observations");
      pull("Brent", "/v1/commodities/spot/BRENT/USD", null);
      pull("FX", "/v1/fx/rates/USD?currencies=EUR,IDR", "rates");
      pull("Fed", "/v1/predictions/policy-paths/federal-reserve", "meetings");
    }
  3. pullAll を実行する エディターから pullAll を実行して、タブを埋めます。レスポンスが空でない場合、ヘルパーは書き込み先のタブをクリアし、ヘッダー行とそれに続くデータを書き込みます。そのため、数式はそれらのタブの外に置いてください。空のリストは何も書き込みません。列名はすべての行から集めるので、最初の値が null でも列が隠れることはありません。

日付や 2026-09 のような期間を含むテキスト列は、スプレッドシートに日付へ変換されないよう、プレーンテキストのままにします。1.0823 のように文字列で送られる小数値は、数値として扱われます。以下の呼び出しは、同じヘルパー、API のベース URL、スクリプトプロパティを使います。それぞれ、書き込み先のタブ、リクエストのパス、レスポンスのフィールドを指定します。

スケジュールで実行する

  1. トリガーを開く Apps Script エディターの時計アイコンを使って、トリガーを開きます。
  2. 時間主導型トリガーを追加する pullAll の時間主導型トリガーを、たとえば毎日実行するように追加します。このトリガーは、エディターからデータタブを埋めるときと同じ関数を呼び出します。

カスタム関数でも URL Fetch は呼び出せますが、シートが再計算されるたびに再実行され、そのたびにリクエストを消費します。メニュー項目や時間主導型トリガーから実行する関数なら、値を 1 回だけ書き込みます。

Google スプレッドシートで祝日を調べる

2026年のアメリカの祝日を Holidays に取り込みます。レスポンスのリストは holidays で、各エントリに date と name があります。ヘルパーは両方のフィールドを列として書き込み、日付のテキストはそのまま保ちます。祝日の行を専用のタブに入れたいときは、この呼び出しを共通のスクリプトと一緒に使ってください。

祝日の取得
pull(
  "Holidays", "/v1/calendars/holidays/USA/2026", "holidays"
);
// Read date and name in the Holidays tab.

Google スプレッドシートで発表日を調べる

2026年11月のアメリカの経済指標の発表カレンダーを Releases に取り込みます。レスポンスから releases を読み取ると、各エントリに at、period、topic、status があります。このリクエストは発表日用です。期間に対応する経済指標の値が必要な場合は、CPI の観測値の呼び出しを使ってください。

発表日の取得
pull(
  "Releases",
  "/v1/economics/calendar?countries=USA&start_date=2026-11-01" +
    "&end_date=2026-11-30&limit=100",
  "releases",
);
// Read at, period, topic and status in the Releases tab.

Google スプレッドシートで経済データを調べる

開始を 2025年9月に指定して、アメリカの CPI 観測値を CPI に取り込みます。レスポンスのリストは observations で、タブの列は period と value です。最初に取得したあとで、ヘッダー行を確認してください。前月比を計算するときは、月が欠けても数式がずれないよう、期間のテキストで各月を検索します。

CPI の取得
pull(
  "CPI", "/v1/economics/USA/cpi/observations?start=2025-09", "observations"
);
// Read period and value in the CPI tab.

2026年9月を2026年8月と比べる場合は、CPI タブの外で下の数式を使います。各 VLOOKUP は CPI!A:B から指定した月を探し、計算では 9 月の値を 8 月の値で割って 1 を引きます。

CPI の前月比
=VLOOKUP("2026-09",CPI!A:B,2,FALSE)/VLOOKUP("2026-08",CPI!A:B,2,FALSE)-1

Google スプレッドシートでコモディティのスポット価格を調べる

USD 建ての Brent スポット価格を Brent に取り込みます。price フィールドは、レスポンスのオブジェクトから読み取ります。この呼び出しはリストのキーに null を渡すので、ヘルパーはオブジェクト全体を 1 行として扱い、フィールドを列名の下に書き込みます。

Brent の取得
pull(
  "Brent", "/v1/commodities/spot/BRENT/USD", null
);
// Read price in the Brent tab.

Google スプレッドシートで為替レートを調べる

USD を基準にした EUR と IDR の為替レートを FX に取り込みます。rates のリストでは、各エントリに currency と rate があります。タブを読むときは、各レートが通貨と対応したままになるよう、これらの列を一緒に扱ってください。

為替の取得
pull(
  "FX", "/v1/fx/rates/USD?currencies=EUR,IDR", "rates"
);
// Read currency and rate in the FX tab.

Google スプレッドシートで予測市場の確率を調べる

連邦準備制度の政策パスを Fed に取り込みます。レスポンスのリストは meetings で、各エントリに resolves_at、p_cut、p_hold、p_hike があります。利下げ、据え置き、利上げの確率が会合と対応したままになるよう、確定時刻を確率と一緒に読んでください。

Fed の取得
pull(
  "Fed", "/v1/predictions/policy-paths/federal-reserve", "meetings"
);
// Read resolves_at, p_cut, p_hold and p_hike in the Fed tab.

IMPORTDATA や IMPORTXML を使わないのはなぜですか?

IMPORTDATA と IMPORTXML は、Authorization ヘッダーを送れません。Narwhal API のリクエストには Bearer ヘッダーが必要なので、UrlFetchApp を使った Apps Script でリクエストします。ヘルパーはスクリプトプロパティからキーを読み、レスポンスを取得する前にヘッダーを付けます。

祝日データで NETWORKDAYS を使えますか?

はい。Holidays タブの date 列を、NETWORKDAYS の祝日の引数に使います。祝日の名前ではなく、その列の日付を使ってください。このスクリプトの祝日リクエストは、2026年のアメリカの祝日の日付を取得します。

CPI のレスポンスが、リクエストした期間より後から始まることがあるのはなぜですか?

すべてのアカウントで全履歴を取得できます。系列が指定した開始日より後に始まる場合、レスポンスはその最初の観測値から始まります。

公開。

次のステップ