pnclFEED Free key

pinnacle odds api / google sheets / apps script

Pinnacle odds API in Google Sheets

loop[every 15 minutes, 96 calls a day]

GET/kit/v1/markets?event_type=prematch&sport_id=1

rows written to the Odds tab200 OK

A short Apps Script calls the Pinnacle odds API for the prematch soccer board and writes one row per match: kick-off, league, teams and the 1X2 prices. A time trigger reruns it every 15 minutes, which is 96 calls a day and fits inside a free key.

Create a free key

$0 · 100 calls a day · no card

Odds tabexample row from the docs
RowABCDEFG
1StartsLeagueHomeAway1X2
24 May 16:30Italy - Serie ACremoneseLazio2.453.302.90
3one row for every match on the prematch board

The script

It reads your base URL and key from the script's properties, so neither sits in the code. It asks for event_type=prematch and sport_id=1, soccer, then flattens each event's full-match money line into columns E to G.

A failed call writes nothing and logs the response, so a bad minute never blanks the tab. Change SPORT_ID for another sport; the IDs are on the home page.

Code.gs
// Extensions > Apps Script, then paste.
const PROPS = PropertiesService
  .getScriptProperties();
const BASE = PROPS.getProperty('BASE');
const KEY = PROPS.getProperty('KEY');
const SPORT_ID = 1; // 1 = soccer

function refreshOdds() {
  const url = BASE + '/kit/v1/markets' +
    '?event_type=prematch&sport_id=' +
    SPORT_ID;
  const res = UrlFetchApp.fetch(url, {
    headers: { 'x-portal-apikey': KEY },
    muteHttpExceptions: true,
  });
  if (res.getResponseCode() !== 200) {
    console.warn(res.getContentText());
    return;
  }
  const data = JSON.parse(
    res.getContentText());
  const rows = data.events.map((ev) => {
    const p = ev.periods || {};
    const ml = (p.num_0 || {})
      .money_line || {};
    return [new Date(ev.starts),
      ev.league_name, ev.home, ev.away,
      ml.home || '', ml.draw || '',
      ml.away || ''];
  });
  const sheet = SpreadsheetApp
    .getActive().getSheetByName('Odds');
  sheet.clearContents();
  sheet.appendRow(['Starts', 'League',
    'Home', 'Away', '1', 'X', '2']);
  if (rows.length) {
    sheet.getRange(2, 1, rows.length, 7)
      .setValues(rows);
  }
}

set it up once

Five steps, then it runs by itself

  1. Add a tab named Odds to your spreadsheet.
  2. Open Extensions, then Apps Script, and paste the script over the empty function.
  3. In Project Settings, add two script properties: BASE, the API address from the docs, and KEY, your key.
  4. Run refreshOdds once and allow the permissions Google asks for.
  5. Under Triggers, add a time-driven trigger for refreshOdds on a 15-minute timer.

What a trigger costs against the daily limit.

TriggerCalls a dayPlan
Every 15 minutes, one sport96Free key
Every 30 minutes, two sports96Free key
Every 15 minutes, two sports192poll
Every minute, one sport1,440poll

Apps Script's own quotas apply on top; the shortest time trigger is one minute.

NEXTrefreshOdds()

A key, a tab, a trigger

The free key covers a 15-minute sheet for one sport. If the sheet becomes a model that needs every sport every minute, poll's 10 calls a second is the next step; the pricing page has the numbers.