pnclFEED Free key

Quickstart notes

Run your odds script every 15 minutes with cron

A cron entry every 15 minutes runs your fetch 96 times a day, inside the free key's allowance. Turn the polling loop into a single run and schedule it.

The Pinnacle odds API free key allows 100 requests a day, and the Python quickstart already notes that one call every 15 minutes fits inside it all day. The cleanest way to keep that rhythm is not a sleeping loop but cron: 96 runs a day, each one a single fetch, no process to babysit.

From loop to single run

The quickstart script polls in a while loop with a sleep at the bottom. For cron, invert it: one run does one fetch and exits. Keep the cursor from each response's last value in a small file, read it at startup, and the next run sends it as since, so every run after the first fetches only what changed.

import json, os, requests

BASE, KEY = os.environ["ODDS_BASE_URL"], os.environ["ODDS_API_KEY"]
CURSOR = "/opt/odds/cursor.txt"

since = open(CURSOR).read().strip() if os.path.exists(CURSOR) else None
params = {"sport_id": 2}
if since:
    params["since"] = since
r = requests.get(BASE + "/kit/v1/markets", params=params,
                 headers={"x-portal-apikey": KEY}, timeout=10)
r.raise_for_status()
data = r.json()
open(CURSOR, "w").write(str(data["last"]))
for ev in data["events"]:
    print(ev["home"], "v", ev["away"])

A run that fails on a 429 simply exits: the next scheduled run is the retry, which matches the quickstart's rule of waiting out the Retry-After period rather than hammering.

The cron entry

Three lines in the crontab set the environment and the schedule:

ODDS_BASE_URL=https://your-base
ODDS_API_KEY=your-key
*/15 * * * * flock -n /tmp/odds.lock /usr/bin/python3 /opt/odds/fetch.py >> /var/log/odds.log 2>&1

The details that bite: cron runs with a minimal environment, so export the variables in the crontab itself; use full paths to the interpreter and the script; and wrap the run in flock so a slow run never overlaps the next one.

Watch the log, not the process

With no daemon, the log file is the health check. Print one line per run with the event count, and a full day of lines tells you the schedule works. If the log stops growing, cron is where you look first: a wrong path or a missing variable fails silently at 3 a.m.

When cron stops fitting

Cron suits anything that can run and exit. The moment you need prices faster than once a minute, or you want drops pushed to you, the shape changes: the drop stream is one connection held open, which belongs in a service, not in a crontab. The quickstart shows both shapes, and the pricing page lists the allowances each one runs inside, checked 2026-10-02.

One fetch per run, 96 runs a day, zero daemons. Cron is the smallest scheduler that keeps a free-key budget honest.