Soft Book Lag: 1xBet Follows Pinnacle in 6 Minutes, Bet365 in 67

Soft book lag: how fast 1xBet and Bet365 follow Pinnacle line moves
How To Guides September 13, 2026

Pinnacle moves a Premier League price 67 times in the last 24 hours before kick-off. Bet365 moves the same price seven times. That gap is the whole reason people watch the sharp line, and almost nobody measures how long the soft books take to answer it.

So we measured it. 28 played fixtures, four competitions, three bookmakers, every active snapshot in the final 24 hours. The result splits along the bookmaker, not the competition. 1xbet answers a Pinnacle move in a median of 6.3 minutes on the Premier League. bet365 takes 66.8 minutes on the same fixtures.

Why you cannot get this from a normal odds feed

Measuring lag needs price history at snapshot resolution, for more than one book, on a fixture that has already finished. Most feeds fail on at least one of those:

  • Live-only APIs hand you the current price. Once the match kicks off, the board is gone and so is the evidence.
  • Daily or hourly closing-line exports flatten the exact thing you want to see. A 6-minute lag disappears inside an hourly bucket.
  • Paid history tiers price this as an enterprise add-on, which is why most public work on line movement uses two books and a screenshot.

OddsPapi keeps every snapshot and serves it on the free tier. A finished fixture reports hasOdds: false from /fixtures, because the live board is dropped, but /historical-odds still returns the full price history for that fixture. The catalogue behind it runs to 350+ bookmakers.

What you need Typical odds API OddsPapi
Price history after the whistle Dropped with the live board Full snapshot history, retained
Resolution Opening and closing price Every recorded price change
Sharp reference Rarely carried Pinnacle, SBOBet, Singbet
Cost of history Paid tier or sales call Free tier
Books per fixture ~20 soft books 350+ in the catalogue, across sharps, softs and exchanges

The study

28 fixtures that kicked off between 28 August and 1 September 2026, seven from each of four competitions: the Premier League, the Eredivisie, the Eliteserien and Liga MX Apertura. For each fixture we pulled pinnacle, bet365 and 1xbet on market 101, the Full Time Result, and kept every snapshot flagged active: true in the 24 hours before kick-off. That gave 1,234 qualifying Pinnacle moves to match against 1xBet and 1,353 against Bet365.

A “move” is a price change of 1% or more on one of the three outcomes. A “follow” is the soft book’s next price change in the same direction, within six hours.

How often each book reprices

Competition Pinnacle 1xBet Bet365
Premier League 67 38 7
Eredivisie 73 18.5 6
Eliteserien 60 17 8
Liga MX Apertura 36 19 5
Median price changes on the home outcome, final 24 hours before kick-off. Seven fixtures per competition.

Pinnacle works the Eredivisie as hard as the Premier League and halves its effort on Liga MX. 1xBet doubles its rate for the Premier League and runs flat everywhere else. Bet365 posts five to eight prices whatever the fixture, which is a repricing budget rather than a response to the market.

How long the soft books take to answer

Counting a “follow” needs a control, because a book that reprices constantly will land near a Pinnacle move by accident. So we ran the same measurement from random timestamps inside the same window. If the observed lag matches the random-timestamp lag, the book is not following anything.

Competition 1xBet lag 1xBet control Bet365 lag Bet365 control
Premier League 6.3 min 53.1 min 66.8 min 161.2 min
Eliteserien 9.8 min 89.6 min 61.3 min 137.2 min
Eredivisie 11.6 min 79.5 min 47.3 min 135.9 min
Liga MX Apertura 12.5 min 96.6 min 48.2 min 115.7 min
Median minutes from a Pinnacle move of 1% or more to the soft book’s next move in the same direction. Control column is the same measure taken from a random timestamp in the window.

1xBet beats its own control by seven to nine times. It tracks Pinnacle, and the coupling is not an artefact of how often it reprices. Bet365 beats its control by 2.2 to 2.9 times, which is coupling you can detect but not coupling you can time a bet around. 1xBet answered 83.1% to 93.8% of qualifying Pinnacle moves inside six hours. Bet365 answered 59.2% to 72.9%, and it has to miss some, because Pinnacle makes ten times as many moves as Bet365 has slots to fill.

The part of the hypothesis that failed

We started from a common claim: smaller competitions are watched less, so the soft books lag further behind on them. Half of that holds.

1xBet’s median lag goes from 6.3 minutes inside the big five to 11.0 minutes outside it. That is a real 1.75x slowdown across 804 moves. Bet365 runs the other way. Its median is 66.8 minutes on the Premier League and 53.0 minutes outside the big five, so the competition tier tells you nothing about when Bet365 will move.

Which book you watch matters more than which competition you watch. The spread between 1xBet and Bet365 on one competition is five to ten times wider than the spread between competitions at either book.

The standing price gap is margin, not staleness

Do not read a price difference as a stale line. The soft books sit below Pinnacle most of the time because they hold more margin, and that gap is there whether or not anybody has moved recently.

Competition Pinnacle 1xBet Bet365
Premier League 2.86% 3.10% 5.73%
Eredivisie 3.80% 3.20% 5.64%
Eliteserien 3.03% 5.26% 6.86%
Liga MX Apertura 3.36% 4.24% 5.68%
Median closing 1X2 margin, last active snapshot before kick-off.

1xBet closed the Eredivisie at 3.20% against Pinnacle’s 3.80%, so the sharp book is not automatically the tightest price outside the top tier. That matches what we found ranking books on African league boards. Subtract the margin before you compare two books, or use the no-vig calculation.

Run the measurement yourself

Step 1: authenticate and resolve the market ID

The key goes in the query string as apiKey, never in a header. Resolve the market by name rather than hardcoding an ID, because the same bet ships under more than one ID across sports.

import os, time, requests
from datetime import datetime, timedelta, timezone
from statistics import median

API_KEY = os.environ["ODDSPAPI_API_KEY"]
BASE = "https://api.oddspapi.io/v4"
SOCCER = 10
SHARP = "pinnacle"
SOFT = ["bet365", "1xbet"]


def call(path, **params):
    """One GET with a 429-aware retry. /historical-odds needs ~4.6s between calls."""
    params["apiKey"] = API_KEY
    for _ in range(4):
        r = requests.get(f"{BASE}/{path}", params=params, timeout=180)
        body = r.json()
        if r.status_code == 200 and "error" not in body:
            return body
        time.sleep(body.get("error", {}).get("retryMs", 3000) / 1000 + 0.5)
    raise RuntimeError(f"{path} failed: {r.status_code} {r.text[:200]}")


markets = call("markets")
m = next(x for x in markets if x["sportId"] == SOCCER
         and x["marketType"] == "1x2" and x["period"] == "fulltime")
MARKET_ID, HOME = str(m["marketId"]), "101"
print(MARKET_ID, m["marketName"])
# 101 Full Time Result

Step 2: find a fixture that has already been played

Lag is only visible after the fact, so the study runs on finished fixtures. Two traps here. A finished fixture reports hasOdds: false, which does not mean the history is gone. And /fixtures rejects a range wider than 10 days when sportId is the only filter, so pass tournamentId as well. It is undocumented, it works, and it cuts the payload about 20x.

today = datetime.now(timezone.utc)
fixtures = call("fixtures", sportId=SOCCER, tournamentId=17,   # 17 = Premier League
                **{"from": (today - timedelta(days=30)).strftime("%Y-%m-%d"),
                   "to": (today - timedelta(days=2)).strftime("%Y-%m-%d")})

played = sorted(
    (f for f in fixtures if f.get("statusName") == "Finished"),
    key=lambda f: f["startTime"], reverse=True)
fixture = played[0]
kickoff = datetime.fromisoformat(fixture["startTime"].replace("Z", "+00:00"))
window_start = kickoff - timedelta(hours=24)
print(f"{fixture['participant1Name']} v {fixture['participant2Name']}  KO {kickoff:%Y-%m-%d %H:%M}Z")
# Aston Villa v Arsenal FC  KO 2026-08-31 19:00Z

Step 3: pull the price history

/historical-odds takes at most three bookmakers per call and returns HTTP 400 TOO_MANY_BOOKMAKERS on a fourth. Worse, a three-slug batch containing one slug your key cannot read returns nothing at all, so the two readable books are lost with it. Retry a failed batch one slug at a time, and retry once. There is also no market filter, so every response carries every market the book priced. Budget 4.6 seconds between calls.

hist = call("historical-odds", fixtureId=fixture["fixtureId"],
            bookmakers=",".join([SHARP] + SOFT))
# top-level key is "bookmakers", not "bookmakerOdds"
# players["0"] is a LIST of snapshots on this endpoint, not a single price

Step 4: collapse snapshots into price-change events

The feed records a snapshot whether or not the price moved, so raw snapshot counts measure polling, not repricing. Collapse consecutive identical prices first. Drop snapshots flagged active: false, and filter to createdAt < startTime, because snapshots keep running through the match and one in-play price will wreck the series.

def price_changes(book):
    """Active snapshots in the final 24h, collapsed to price-change events."""
    outcome = book.get("markets", {}).get(MARKET_ID, {}).get("outcomes", {}).get(HOME)
    if not outcome:
        return []
    snaps = sorted(
        (datetime.fromisoformat(s["createdAt"].replace("Z", "+00:00")), s["price"])
        for s in outcome["players"]["0"] if s["active"])

    events, previous = [], None
    for stamp, price in snaps:
        if window_start <= stamp < kickoff:
            if previous is not None and price != previous:
                events.append((stamp, price, previous))
            previous = price
        elif stamp < window_start:
            previous = price
    return events

Step 5: measure the lag

sharp_moves = price_changes(hist["bookmakers"][SHARP])
print(f"{SHARP}: {len(sharp_moves)} price changes in the final 24h")

for slug in SOFT:
    soft_moves = price_changes(hist["bookmakers"][slug])
    lags = []
    for stamp, new, old in sharp_moves:
        if abs(new - old) / old < 0.01:          # ignore sub-1% ticks
            continue
        direction = 1 if new > old else -1
        follow = next((s for s in soft_moves
                       if s[0] > stamp and (1 if s[1] > s[2] else -1) == direction), None)
        if follow:
            lags.append((follow[0] - stamp).total_seconds() / 60)
    print(f"{slug}: {len(soft_moves)} changes, followed {len(lags)} sharp moves, "
          f"median lag {median(lags):.1f} min")

Output on Aston Villa v Arsenal, 31 August 2026:

pinnacle: 181 price changes in the final 24h
bet365: 11 changes, followed 46 sharp moves, median lag 87.5 min
1xbet: 47 changes, followed 51 sharp moves, median lag 4.9 min

One fixture reproduces the shape of the whole study. Run it across a round of fixtures and the medians settle where the tables above put them.

What to do with the number

A 6-minute follow window is not a strategy on its own. It tells you three things about how to build:

  • Poll the sharp book, not the soft one. Pinnacle carries ten times the information per unit of time. Polling Bet365 at one-minute resolution wastes 59 of every 60 calls. Better still, take the push feed: OddsPapi’s WebSocket sends the change instead of making you ask for it.
  • Set your alert threshold on the book you are watching. A steam-move detector tuned to Pinnacle’s cadence will fire constantly against Bet365 and rarely against 1xBet.
  • Grade against the close, not against a mid-window price. A soft book’s price 30 minutes after a sharp move may be neither its own opinion nor Pinnacle’s. The CLV method is built for exactly this problem.

If you want to run this across a season rather than a round, read how many bookmakers a backtest actually needs first. The three-per-call cap on /historical-odds shapes the whole pull, and 25 books is where the consensus curve flattens. To keep the results, push the snapshots into a local SQLite store rather than re-pulling them.

Caveats

  • Seven fixtures per competition is enough to separate a 6-minute median from a 67-minute one. It is not enough to rank two books that finish 10 minutes apart.
  • The window is the final 24 hours. Books behave differently further out, and Pinnacle opens some fixtures weeks ahead.
  • “Follow” means the next same-direction move. It does not prove Bet365 or 1xBet reads Pinnacle. Both may react to the same underlying news.
  • Every number here comes from calls made on 4 September 2026. A board describes the moment you measured it.

Get the data

The free tier covers all of it: the full snapshot history, the sharp books, and a 350+ bookmaker catalogue behind one fixture ID. No sales call and no history add-on.

Get your free OddsPapi API key and re-run the study on your own competitions.

FAQ

How fast do soft bookmakers follow Pinnacle?

It depends on the book, not the competition. Across 28 fixtures, 1xBet’s next same-direction move landed a median of 6.3 to 12.5 minutes after a Pinnacle move of 1% or more. Bet365 took 47.3 to 66.8 minutes on the same fixtures.

How often does Pinnacle change its price before kick-off?

On a Premier League fixture, a median of 67 price changes on the home outcome in the final 24 hours. The Eredivisie ran slightly higher at 73 and Liga MX Apertura ran lower at 36.

Can I get historical odds for a match that has already finished?

Yes. /fixtures reports hasOdds: false for a finished fixture because the live board is dropped, but /historical-odds still returns the full snapshot history for that fixture ID on the free tier.

How many bookmakers can I request per historical-odds call?

Three. A fourth returns HTTP 400 TOO_MANY_BOOKMAKERS, and a batch containing one bookmaker your key cannot read returns nothing at all, so retry failed batches one slug at a time.

Is a price gap between two bookmakers a sign of a stale line?

Usually not. Soft books hold more margin, so they sit below the sharp price all the time. Bet365 closed between 5.64% and 6.86% margin on the four competitions against Pinnacle’s 2.86% to 3.80%. De-vig both books before you compare them.