Line movement API: open to close

Line movement API with every price change from the opening line to the close, per book, for line charts, steam alerts and closing line value tracking.

PreciseAPI’s line movement API records every price and line change for full-game moneylines, spreads and totals at each book, from the first price it saw to the close. /v1/history returns one market’s open, current and every point in between for 3 credits.

A line movement API records where a price opened, every move it made and where it stood at kickoff, book by book. PreciseAPI keeps that record for the main full-game markets, moneyline, spread and total, at every sportsbook and exchange it collects, and serves it from /v1/history. The same record, the raw material of line movement analysis, drives line charts, steam alerts, closing line value tracking and backtests. This page covers what is recorded, the endpoint, how to find the closing line, the CLV math, line-move alerts, and the MCP tool that summarizes moves across books.

What gets recorded

Each book's moneyline, spread and total for the full game gets a history. A point is added whenever the line or a price changes; a read that shows the same line and prices as the last one adds nothing, so a quiet book doesn't look busy. Each point has a timestamp t (ISO 8601, UTC), the line, and prices in the market's outcome order: home then away for moneylines and spreads, over then under for totals, and home, draw, away for three-way soccer moneylines.

open is the first price PreciseAPI recorded for that market at that book. It is the book's true opener only if the market was being collected when the book posted it. A market keeps its most recent 500 changes, with the opening point kept apart, and history is held for 48 hours after the market stops updating, so archive what you want to keep.

Line movement API: /v1/history

Ask for a market by the market_id from any odds response, or by event_id and book with market set to moneyline (the default), spread or total. Each call returns one market at one book and costs 3 credits. format works as on every odds endpoint.

curl "https://api.preciseapi.com/v1/history?event_id=evt_01a7mgfh0nd&book=pinnacle&market=moneyline" \
  -H "Authorization: Bearer $PRECISEAPI_KEY"
{
  "data": {
    "market_id": "mkt_1sutc886rth",
    "open": { "t": "2026-10-14T23:33:15.863Z", "line": null, "prices": [-715, 567] },
    "current": { "t": "2026-10-14T23:33:39.269Z", "line": null, "prices": [-720, 570] },
    "points": [
      { "t": "2026-10-14T23:33:15.863Z", "line": null, "prices": [-715, 567] },
      { "t": "2026-10-14T23:33:17.539Z", "line": null, "prices": [-716, 567] },
      { "t": "2026-10-14T23:33:24.132Z", "line": null, "prices": [-717, 568] }
    ]
  },
  "meta": { "request_id": "req_…", "credits_used": 3, "credits_remaining": 149655, "generated_at": "2026-10-14T23:33:43.642Z" }
}

Line history is on every paid plan. A game in progress is the exception: its history runs into in-play prices, so while it is live only Syndicate can read it. On Edge and Sharp, read it before kickoff or once the game is final.

A line history API across books

/v1/history returns one book at a time. To compare how books moved, store the market_id of each book's market from /v1/odds and request each one, or use the MCP tool below, which puts every book's open and current price side by side in one call. The historical odds API page covers the same records from the archiving side.

The closing line API pattern

There is no separate closing endpoint, because the close is easy to derive: it is the last recorded point before the event's start_time. Statuses go from scheduled to live to final, and in-play prices are a different market, so filter by timestamp rather than taking the latest point. That makes /v1/history a closing line API with one filter applied.

Timing matters. A lookup by event_id works while the event is in the feed, at least four hours after it ends; a lookup by market_id works for as long as the history is kept. On busy markets, in-play changes can push older points past the 500-change limit, so the safest time to read the close is right at kickoff. Store your closing odds data in your own database and you never depend on retention.

Closing line value math

Closing line value compares the price you took with the closing price. The cleanest version de-vigs the close at a sharp book and treats it as the fair probability:

CLV = fair closing probability × decimal price taken − 1

Say you took an underdog at +125 (2.25) and Pinnacle closed the game at −130 / +118. The implied probabilities are 56.52% and 45.87%, which add up to 102.39%. De-vigged, the underdog's fair closing probability is 44.80%, so CLV = 0.4480 × 2.25 − 1 = +0.8%. You beat the close by a little under one percent. Beating the close consistently is the usual sign that bets were taken at good prices, which is why closing line value data matters more than short-run results.

This script finds the close for one game and computes CLV, 4 credits in all:

import os
import requests

API = "https://api.preciseapi.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PRECISEAPI_KEY']}"}

def get(path, **params):
    r = requests.get(f"{API}/{path}", params=params, headers=HEADERS, timeout=10)
    r.raise_for_status()
    return r.json()["data"]

event_id = "evt_0uuc6p2dsqa"
event = get(f"events/{event_id}")
h = get("history", event_id=event_id, book="pinnacle", market="moneyline", format="decimal")

pre_game = [p for p in h["points"] if p["t"] < event["start_time"]]
close = pre_game[-1] if pre_game else h["open"]  # last point before the start

implied = [1 / d for d in close["prices"]]  # moneyline order: home, away
fair = [p / sum(implied) for p in implied]

taken = 2.25  # decimal price you took on the away side
print(close["t"], close["prices"], f"CLV {fair[1] * taken - 1:+.2%}")

PreciseAPI isn't a CLV API that tracks your bets; it supplies the closing prices, and the comparison runs in your code. How to measure closing line value covers the other CLV definitions, and the no vig odds API page covers de-vig methods.

Line-move alerts and steam

You don't have to poll the line movement API to react to moves. Line-move alert rules watch the feed and fire a line.moved event when a full-game moneyline, spread or total price moves by at least the number of cents you set (20 by default), or when a spread or total line changes. Rules can be narrowed to leagues, books and markets, and each alert goes to a signed webhook, an email, or both, for 1 credit per delivered alert. A rule fires at most once every 10 minutes per market. Edge includes 10 rules and 2 webhook endpoints, Sharp 100 and 10, and Syndicate 500 and 25; moves during games in progress are alerted on Syndicate only.

A steam move is the same move at several books within a short window. Detect steam moves builds a detector on the Syndicate WebSocket stream, which pushes every price change as it happens, and the odds alerts webhooks docs cover the payload and signature check.

get_line_history over MCP

Connect Claude, ChatGPT, Cursor or another AI client to the PreciseAPI MCP server and get_line_history summarizes a game's moves for you. Give it an event_id and a market (spread by default). With a book, it returns that book's timeline with open and current prices. Without one, it lists open and current at every book with the line move, the number of changes, and when each book first posted and last moved, biggest moves first. Each call costs 3 credits on any paid plan.

{
  "market": "Spread",
  "books": [
    {
      "book": "Pinnacle",
      "open": "Kansas City Chiefs -2.5 -105 / Buffalo Bills +2.5 -105",
      "current": "Kansas City Chiefs -3.5 -102 / Buffalo Bills +3.5 -108",
      "line_move": -1,
      "changes": 14,
      "first_seen": "Sun, Nov 8, 6:12 PM EST",
      "last_change": "Wed, Nov 11, 11:40 AM EST"
    }
  ]
}

The server's "Line movement" prompt asks it to find a team's next game and call out the biggest moves and which books moved first. Setup is in the odds API MCP guide.

What isn't recorded

Plans and credit costs

EdgeSharpSyndicate
Price$49.99 / month$199.99 / month$249.99 / month
/v1/history, get_line_history (3 credits)Pre-game and final gamesPre-game and final gamesAlso games in progress
Alert rules / webhook endpoints10 / 2100 / 10500 / 25
WebSocket streamNoNoYes

Edge includes 150,000 credits a month; Sharp and Syndicate are unlimited. The free Sandbox has 50 credits for the dashboard chat and no API access, so a line movement API integration starts on Edge. See odds API pricing.

Frequently asked questions

Does the line movement API return the closing line?

Not as a separate field. The close is the last point in /v1/history before the event's start_time, which takes one filter, as in the script above.

How far back does line history go?

From the first price PreciseAPI recorded for a market until 48 hours after it stops updating. It is not a multi-season archive, so store the history you need.

Is line history available on Edge?

Yes, on every paid plan. While a game is in progress its history is in-play data, which only Syndicate can read; on Edge and Sharp, read it before kickoff or after the final.

Can I get alerts when a line moves?

Yes. Line-move alert rules send a signed webhook or an email when a price moves by your threshold or a line changes, for 1 credit per alert.

From the open to the close

/v1/history returns the opening point, the current point and every recorded change in between, each with a timestamp, the line and the prices in outcome order. A point is added only when the line or a price changes. The closing line is the last point before the event’s start_time, so closing line value takes one filter and a de-vig. History is kept for 48 hours after a market stops updating, so archive what you need.

Alerts and summaries

Line-move alert rules fire when a full-game price moves by the cents you set, 20 by default, or when a spread or total line changes, and deliver a signed webhook or an email for 1 credit each. Over MCP, get_line_history lists every book’s open and current price with the size of the move and the number of changes, biggest first. History is on every paid plan; reading a game in progress needs Syndicate.

Example request

GET /v1/history?event_id=EVENT_ID&book=pinnacle&market=spread

Endpoint

What teams build with it

Related reading

More products

Responses use the same event, market and outcome ids as every other endpoint. Prices are American odds by default, with format=decimal and format=probability for the other two, and a market whose source has stopped reporting is flagged suspended instead of being shown as live.

Every source and league is on the coverage page, and what each request costs is on the pricing page.