pnclENGINEGet API access

MONITORING

Monitoring a Pinnacle odds pipeline.

A pipeline that polls the Pinnacle odds API fails quietly more often than loudly: prices stop moving, a cursor stalls, a worker backs off and never comes back. Five metrics catch those failures, and each threshold follows from the poll interval and the plan you are on.

The five metrics

Record them per board, meaning per sport and phase, because a live tennis board and a prematch soccer board fail independently. One counter per poll is enough to derive all five.

MetricHow to measure itAlert when
Snapshot ageSeconds since the last poll that returned a valid envelopeAbove three poll intervals during a slate
Cursor progressThe last value from each response, compared with the previous oneUnchanged for 30 minutes while events on the board are in play
Poll latencyTime from request to parsed response, p50 and p95p95 above 2 seconds for 10 minutes
Error rateResponses by status per hour: 2xx, 429, 5xx, timeouts429 above 1% of requests, or any 401 or 403
Request rateRequests per second at peak, and per day on the free keyAbove 70% of the plan ceiling, or 90 of the free 100 a day

Snapshot age is the one that matters

Every other failure shows up here eventually, which makes age the metric to put on the wall. Compute it from the last successful, validated poll, not the last attempt: a poller that receives 5xx every ten seconds is attempting constantly and succeeding never. Expose the same number to your consumers next to the prices, so a dashboard can label a stale board instead of showing old prices as current. The public match desk on pnclHUB does exactly this, withholding prices when the source's freshness is unconfirmed rather than showing them with a caveat.

The threshold scales with the interval. Polling live boards every 5 seconds, alert at 15; polling prematch every 30, alert at 90. Outside a slate, a board with no events can legitimately go quiet, so gate the alert on the board carrying events whose start time has passed.

Cursor progress and the empty delta

The since cursor makes a poll return only what changed, and a healthy live board returns something most cycles. A cursor that stops advancing while matches are in play means one of three things: the poller is sending a stale cursor, the response is being discarded before the cursor is stored, or the feed itself has stalled. Log the cursor with each poll and the first two are visible in a minute. The polling discipline in REST integration covers where the cursor should live so a restart resumes from it.

Budget metrics

Requests per second against the ceiling is the number that predicts tomorrow's 429s. Keep the steady state under 70% of the plan's rate, 7 a second on the 10-a-second plan and 21 on the 30-a-second plan, and treat the peak on a match day as the figure to compare, since rejections arrive when boards are busiest. On the free key the daily count is the one to watch: at 90 of the 100 daily requests, stop optional calls so the scheduled ones finish the day. The arithmetic behind the peak is on the capacity planning page.

Where the numbers come from

One structured log line per poll carries everything: board, status, latency, cursor before and after, event count. A metrics layer can derive the five series from those lines, and a log search answers the questions a dashboard cannot, such as which board produced the first 429 on Saturday. Name the series plainly, odds_poll_age_seconds, odds_poll_latency_seconds, odds_poll_total with a status label, and a new engineer reads the dashboard without a legend.

{"board": "soccer/live", "status": 200,
 "latency_ms": 412, "since": 141, "last": 158,
 "events": 7, "at": "2026-09-29T14:03:10Z"}

Add one synthetic check that reads your own store, not the API: fetch a known event from the cache every minute and confirm its age. It catches the failure where the poller runs but the consumers cannot see its work. If the poller uses the SSE stream as well, count reconnects per hour on the same dashboard; the SSE setup guide on pnclPULSE describes what a healthy reconnect cycle looks like.

See capacity plans

Questions this raises

Is snapshot age the same as the vendor's data age?

No. Snapshot age measures your poller. The feed's own freshness is a separate question, and the docs describe prematch refreshing about every 30 seconds while live prices arrive within a fraction of a second. Track both when you can.

How much history should the metrics keep?

Two weeks at full resolution covers two weekends, which is where the peaks are. Longer retention can be downsampled to hourly maxima.

Do I need all five on the free key?

Age and the daily request count are enough for a prototype. Add the rest when the poller moves to a paid plan and a per-second ceiling.

Allowances and refresh figures follow the vendor's published documentation, checked on 26 September 2026. Published .