On the wire · 04:47:54 UTC Live 550 · Prematch 14,364 · Markets 57,018 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Answer · Google Sheets · trigger

Refresh Pinnacle odds in Google Sheets on a timer

Updated · PinnFeed · 1 min read

Answer: Use Apps Script UrlFetchApp against GET /v1/odds, then install a time-driven trigger (every 15 minutes). Full board script: Google Sheets guide. Free plan is enough (30 s delay, 1,000 req/day).

Trigger-only snippet#

const KEY = PropertiesService.getScriptProperties().getProperty("PINNFEED_KEY");
const SPORT = "soccer";

function refreshOdds() {
  const url = "https://pinnfeed.io/v1/odds"
    + "?sport=" + encodeURIComponent(SPORT)
    + "&market=moneyline&main=true&limit=30";
  const res = UrlFetchApp.fetch(url, {
    headers: { "x-api-key": KEY, accept: "application/json" },
    muteHttpExceptions: true,
  });
  if (res.getResponseCode() !== 200) throw new Error(res.getContentText());
  const events = JSON.parse(res.getContentText()).events || [];
  const sheet = SpreadsheetApp.getActive().getSheetByName("Odds");
  const rows = [["home", "away", "home_dec", "away_dec", "fair_home", "updated"]];
  for (const ev of events) {
    const m = (ev.markets || []).find((x) => x.type === "moneyline");
    if (!m) continue;
    const by = Object.fromEntries((m.outcomes || []).map((o) => [o.name, o]));
    rows.push([
      ev.home, ev.away,
      by.home?.decimal, by.away?.decimal, by.home?.fair,
      new Date().toISOString(),
    ]);
  }
  sheet.clearContents();
  sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
}

/** Run once from the editor to install the 15-minute trigger. */
function installTrigger() {
  ScriptApp.getProjectTriggers().forEach((t) => ScriptApp.deleteTrigger(t));
  ScriptApp.newTrigger("refreshOdds").timeBased().everyMinutes(15).create();
}

Store the key in Project settings → Script properties, never in the sheet cells. For Excel instead, see Power Query. Live push still needs Builder (€99/mo). Paid plans: 3-day trial; a card is required and it is charged after day 3 unless you cancel. Educational content for adults (18+).

Questions people ask#

Will 15-minute refreshes burn the Free quota?#

96 calls/day if the trigger fires alone — under the Free 1,000/day cap. Add more sports carefully.

Can IMPORTDATA do this?#

IMPORTDATA cannot send x-api-key. Use Apps Script (this page) or the IMPORTDATA answer only with a carefully designed public proxy you control — we do not provide one.

The WebSocket plan: Builder, €99/mo.

Real-time Pinnacle odds pushed over one WebSocket, all 13 sports, every market, no-vig fair odds and closing lines. 3 days free, cancel in one click.

Form K-1 · Free API key

Get your free API key.

One field. No password, no card: enter your email, click the link we send, and your key is on screen.

By continuing you agree to the Terms and Privacy Policy.

One free key per email. Link valid for 20 minutes.