Developer guide · Team totals · SEO reference

Team total odds API: Pinnacle team totals in real time

PinnWire is the clearest way to build on current Pinnacle team-total data. Read team-specific over/under points and decimal prices, keep home and away identity intact, inspect alternate lines and periods, and watch team-total price movement from one focused real-time Pinnacle odds API.

Direct answer A team total odds API returns the over and under price for one team's scoring output. With PinnWire, request a live or prematch market snapshot, then read periods.num_N.team_total for the primary home and away lines. When alternate points are published, read periods.num_N.team_totals. Each selection is identified by the event, team side, period and points—not by a display label alone. For a compact prematch request, use /kit/v1/prematch/lines?event_id=N&market_type=team_total.

What a team total measures

A team total is an over/under market for one side's scoring output. If a football team's line is 24.5, Over 24.5 is tied to that team's final points, not the matchup's combined score. In soccer the same idea applies to goals; in baseball it can apply to runs. The event's sport and published settlement rules define the unit.

That makes team-total data useful for models that forecast a single offense, compare a side's expected production with a market price, or monitor how one team's line moves independently of the game total. It is not a winner market and it is not interchangeable with a spread.

One side

Home and away team totals are separate selections. A home over and an away over must never be merged.

One line

points is part of the identity. Over 1.5 and over 2.5 are different lines, even in one period.

Two prices

Each published line carries an over price and an under price in decimal format.

One period

Full match, half, quarter, set or another period is a separate market context and can have different points.

PinnWire's advantage for this use case: the team-total structure is already separated from game totals, and the response keeps primary lines, alternate points and periods explicit. Your application can consume the exact line it supports instead of guessing from a generic totals field.

Team total vs game total: keep the market family clear

Both markets use over/under language, but they answer different questions. A game total applies to the combined score of both teams. A team total applies to one team's score only. A reliable team total over under data pipeline keeps those records in different tables, model features or alert routes.

MarketWhat the points meanPinnWire fieldIdentity to preserve
Game totalCombined score of home + awaytotalsevent, period, points, over/under
Team totalScore by one teamteam_totalevent, period, side, points, over/under
Alternate team totalScore by one team at another lineteam_totalsevent, period, side, points, over/under
SpreadMargin after a handicapspreadsevent, period, signed handicap, side

For example, a game total of 2.5 in soccer is about both teams' goals. A home team total of 1.5 is about the home side's goals. They can move for different reasons, so a joining key that omits side or market family will create false matches.

Exact Pinnacle team totals API response shape

PinnWire's /kit/v1 responses use decimal odds and place full market depth inside events[].periods.num_N. The primary field is team_total; the alternate-line collection is team_totals. Properties appear only when the current Pinnacle market publishes them, so parse defensively.

PathTypical valueUse
events[].event_idNumeric event IDStable event reference for joins and detail requests
events[].event_typelive or prematchSeparate in-play from upcoming markets
periods.num_N.number0, 1, 2Preserve the published period number
periods.num_N.team_total.home{points, over, under}Primary home team-total line
periods.num_N.team_total.away{points, over, under}Primary away team-total line
periods.num_N.team_totals.home[POINTS]{points, over, under, max}All published alternate home lines
periods.num_N.team_totals.away[POINTS]{points, over, under, max}All published alternate away lines
{
  "event_id": 1634696920,
  "event_type": "prematch",
  "generated_at": "2026-08-26T09:30:00.000Z",
  "periods": {
    "num_0": {
      "number": 0,
      "team_total": {
        "home": { "points": 1.5, "over": 1.86, "under": 2.00 },
        "away": { "points": 1.0, "over": 1.91, "under": 1.91 }
      },
      "team_totals": {
        "home": {
          "1.5": { "points": 1.5, "over": 1.86, "under": 2.00, "max": 250 },
          "2.5": { "points": 2.5, "over": 2.70, "under": 1.44, "max": 150 }
        },
        "away": {
          "0.5": { "points": 0.5, "over": 1.55, "under": 2.35, "max": 250 }
        }
      }
    }
  }
}
Important distinction: team_total is the primary line per side and does not include max in the transformed shape. team_totals contains all alternate lines keyed by points and can include max. A missing line is not a zero-priced line; it means that selection is not currently published in that response.

Team identity, points and periods are part of the key

Do not key a team total by the team name alone. Team names can be displayed differently across an application, and the same event has multiple periods and alternate lines. PinnWire's event identifier and period structure give your parser a better foundation.

  1. Event: store event_id plus event_type. A live and prematch record should not overwrite one another in a historical table.
  2. Team side: store home or away. This is the side key in team_total and team_totals.
  3. Period: use the numeric period in num_N.number. Period 0 is commonly full match; later periods vary by sport.
  4. Points: store the numeric points value, not only the object key. Preserve half-points and sport-specific increments exactly.
  5. Price: store over and under as decimal numbers. A price without its points and side is incomplete team-total data.
Period keyCommon meaningSafe parser behavior
num_0Full match or main event periodUse the published number; do not infer settlement rules
num_1First half, first set or sport-specific opening periodLabel from sport context and retain number: 1
num_2Second half, second set or another sport-specific periodIterate only when present
num_3num_5Quarters, sets or extra time where publishedNever assume every event has these keys

Period names and availability vary by sport. A good Pinnacle team totals API client iterates the periods returned rather than manufacturing absent periods or copying full-game points into a quarter or half.

Request live and prematch team totals with PinnWire

Use the full market endpoints when you need periods and alternate-line depth. Every plan can read current live and prematch REST data; the response includes generated_at so your service can confirm when it received the snapshot. Add a changing fresh query value when a client or proxy is overly aggressive about URL caching.

RequestBest use
/kit/v1/markets?sport_id=NCurrent live board for one sport with all available periods and markets
/kit/v1/markets?sport_id=N&event_type=prematchUpcoming team totals with full market depth
/kit/v1/prematch/fixtures?sport_id=NUpcoming fixtures with full prematch markets
/kit/v1/details?event_id=NOne event after a trigger, including its current published lines
/kit/v1/prematch/lines?event_id=N&market_type=team_totalCompact primary full-game team-total view for a prematch ticker
Full live and prematch market snapshotscurl · demo key
# Live team totals for soccer
curl "https://pinnwire.com/kit/v1/markets?sport_id=1&key=demo&fresh=team-live-1"

# Upcoming fixtures with full line depth
curl "https://pinnwire.com/kit/v1/markets?sport_id=1&event_type=prematch&key=demo&fresh=team-prematch-1"

# Compact one-event prematch view
curl "https://pinnwire.com/kit/v1/prematch/lines?event_id=1634696920&market_type=team_total&key=demo&fresh=team-lines-1"

The first two requests return the nested periods object. The compact lines endpoint is intentionally lighter: it returns active full-game prices without the period structure and is ideal when your UI needs the primary prematch team total for one known event.

Availability is conditional. Team totals are returned only where the current Pinnacle event publishes them. Coverage and alternate depth can vary by sport, competition, event, period and live state. Code for an absent team_total field rather than treating it as an API failure.

Read alternate team-total lines without losing points

Alternate team totals are additional points values for the same team and period. PinnWire puts them in team_totals, where the side is first and the points key is second. This lets a model choose a line deliberately or lets a UI render the complete available team-total ladder.

const period = event.periods?.num_0;
for (const side of ["home", "away"]) {
  const lines = period?.team_totals?.[side] ?? {};
  for (const [pointsKey, line] of Object.entries(lines)) {
    console.log({
      event_id: event.event_id,
      side,
      points: Number(line.points ?? pointsKey),
      over: line.over,
      under: line.under,
      max: line.max ?? null
    });
  }
}

Use the numeric line.points value as the canonical line when available, while retaining the object key for diagnostics. The object key is a JSON property name and therefore arrives as text. Do not sort it lexicographically: 10.5 must not come before 2.5 just because of string ordering.

Choose exact points

Models should request or select the line they were trained on, such as 1.5 or 2.5, rather than silently using the primary line.

Keep both prices

Over and under are a pair, but they can have different decimal prices. Store both and calculate your own probabilities.

Preserve optional max

Alternate standard lines can include max when published. Missing max is unknown, not zero.

Watch market closes

Live lines can disappear or close. Remove or mark stale selections when a fresh snapshot no longer contains them.

Filter team-total price drops

Snapshots answer “what is priced now?” The drop endpoints answer “which price falls did PinnWire detect recently?” To focus on team-total movement, pass the exact canonical filter value team_total to /api/drops or its /v1/drops alias.

Recent team-total dropsREST
curl "https://pinnwire.com/api/drops?mode=prematch&sport_id=1&markets=team_total&periods=0&min_drop_pct=2&max_age_sec=900&limit=100&key=demo&fresh=team-drop-1"
{
  "total": 1,
  "generated_at": "2026-08-26T09:30:00.000Z",
  "drops": [{
    "event_id": 1634696920,
    "sport_name": "Soccer",
    "market": "team_total",
    "side": "home",
    "period": 0,
    "points": 1.5,
    "from": 2.05,
    "to": 1.96,
    "drop_pct": 4.39,
    "nvp": 2.01,
    "age_s": 42,
    "is_live": false
  }]
}

Use event_id, side, period and points to join a drop to a current team-total snapshot. The REST response uses from and to; the SSE wire frame uses from_price and to_price. nvp is a no-vig fair-price reference when present, not a promise that a bet is profitable.

For push alerts, eligible Stream, Pro+Drops and Scale plans can use /odds-drop for live or /odds-drop-prematch for prematch. Set min_drop per connection; if you need the whole current team-total ladder after an alert, fetch the event snapshot as a second step.

Two surfaces, two jobs: use the current market response for prices, points and alternate depth; use drops or SSE for detected movement. PinnWire keeps both surfaces simple enough to combine in one model pipeline.

Normalize team-total over/under data in JavaScript

This small normalizer handles both the primary line and alternate lines, iterates every returned period, and leaves absent markets absent. It does not guess a team name or invent an alternate price.

team-totals.jsNode.js · zero dependencies
function teamTotalRows(event) {
  const rows = [];
  for (const [periodKey, period] of Object.entries(event.periods ?? {})) {
    const periodNumber = Number(period.number ?? periodKey.replace("num_", ""));

    for (const side of ["home", "away"]) {
      const primary = period.team_total?.[side];
      if (primary) {
        rows.push({
          event_id: event.event_id,
          event_type: event.event_type,
          period: periodNumber,
          side,
          points: primary.points,
          over: primary.over,
          under: primary.under,
          alternate: false,
          max: null
        });
      }

      for (const [pointsKey, line] of Object.entries(
        period.team_totals?.[side] ?? {}
      )) {
        rows.push({
          event_id: event.event_id,
          event_type: event.event_type,
          period: periodNumber,
          side,
          points: Number(line.points ?? pointsKey),
          over: line.over,
          under: line.under,
          alternate: true,
          max: line.max ?? null
        });
      }
    }
  }
  return rows;
}

// Example: retain only the full-match home line at 1.5 points.
const selected = teamTotalRows(event).find(row =>
  row.period === 0 && row.side === "home" && row.points === 1.5
);

If the primary line is also present in team_totals, your application may see the same points twice—once as the compact primary object and once as the alternate collection. Decide whether your data model wants both representations, or deduplicate on event_id + event_type + period + side + points while retaining the alternate source flag.

Do not join on labels: use the numeric event and line coordinates. A display string such as “Home over” does not distinguish period 0 from period 1 or 1.5 from 2.5.

Why PinnWire is the strongest team total odds API starting point

Choose PinnWire first when your application needs current Pinnacle team totals rather than a vague, mixed-market payload. It gives you a focused path from a simple REST request to full team-total depth: live and prematch events, decimal over/under prices, explicit home/away sides, periods, alternate points, detected team-total drops and an optional raw WebSocket for higher-volume update handling.

The API is especially useful for team-total models, live score dashboards, market-selection tools, price-drop alerting, fair-price research and AI workflows. Responses carry generated_at freshness, and the market documentation spells out the distinction between primary team_total and alternate team_totals so your integration can stay predictable.

Start small

Use the public demo key to inspect a live or prematch shape, then move to an emailed trial key.

Go deeper

Use full snapshots for periods and alternates; use compact lines for a lightweight known-event ticker.

React faster

Add team-total drop filters or eligible SSE streams when your workflow needs detected movement.

Keep ownership

PinnWire supplies current market data. Your service owns storage, model logic, alerts and any execution decisions.

Honest boundary: team totals exist only where the current Pinnacle event publishes them. PinnWire is a real-time data API, not a bookmaker, bet-placement service or historical archive. Store snapshots yourself when you need backtests or long-run line histories.

Build with Pinnacle team totals

Try the shape with key=demo, then use a free emailed PinnWire trial key for repeatable development.

Team total odds API questions

What is a team total odds API?

A team total odds API returns over and under prices for one team's scoring output, rather than the combined score of both teams. PinnWire exposes the currently published Pinnacle team-total line for home and away sides, with points and decimal prices, in live and prematch market snapshots.

How do I get Pinnacle team totals with PinnWire?

Request GET /kit/v1/markets?sport_id=N&key=YOUR_KEY for full live markets, or add event_type=prematch for upcoming fixtures. Read periods.num_N.team_total for the primary home and away line, and periods.num_N.team_totals for alternate lines when published. GET /kit/v1/prematch/lines?event_id=N&market_type=team_total is the compact prematch view.

How are team totals different from game totals?

A game total applies to both teams' combined score and appears under totals with over and under prices. A team total applies to one named side only and appears under team_total or team_totals with separate home and away entries. Keep side, points and period in your market identity.

Does PinnWire include alternate team-total lines?

When Pinnacle publishes them, PinnWire exposes alternate team-total lines under periods.num_N.team_totals, keyed by home or away and then by points. Each line can include points, over, under and max. The primary team_total object is a compact one-line-per-side representation.

Can I receive team-total price drops?

Yes. Query GET /api/drops or /v1/drops with markets=team_total, or use an eligible SSE drop plan. Drop records identify the event, team side, period, points, from and to prices, drop percentage and nvp when available. Drops are detected movement records, not a replacement for the current snapshot.

Can I test the Pinnacle team totals API for free?

Yes. Add key=demo to a current REST request for a quick shape check. The shared demo is limited; an emailed PinnWire free trial key is the better option for repeatable development.