Sports scores API: live scores and results
Sports scores API with live scores, the game clock and final results on the same event ids as the odds, for scoreboards, live screens and bet grading.
PreciseAPI’s sports scores API shares event ids with the odds, so a game card or a grading job joins prices and results without matching team names. /v1/scores returns live scores, the game clock and recent finals for 1 credit per call.
- Live scores and clock on every paid plan
- Same event ids as odds and line history
- Final scores kept for four hours
- grade_bet MCP tool for full-game bets
A sports scores API is the other half of an odds product. A live screen needs the score and clock next to each price, and a bet tracker needs the final result to settle what was placed. PreciseAPI serves scores on the same event ids as the odds, so a game card, a model's training set or a grading job joins prices and results without matching team names. This page covers /v1/scores, the event endpoints, grading bets in your own code and with the grade_bet MCP tool, and what the score data does not include.
Sports scores API: /v1/scores
/v1/scores returns events with their status, score and game clock. By default it lists games that are live or recently finished; status takes scheduled, live, final, postponed and cancelled, comma-separated, and league takes one or more league ids. limit defaults to 200 and goes up to 500. Each call costs 1 credit, whatever the number of games.
curl "https://api.preciseapi.com/v1/scores?league=nhl&status=live" \
-H "Authorization: Bearer $PRECISEAPI_KEY"
{
"data": [
{
"id": "evt_27a3vzijsnp",
"league": "nhl",
"sport": "hockey",
"competition": "National Hockey League",
"start_time": "2026-10-14T22:03:23.850Z",
"status": "live",
"home": { "id": "nhl_det", "name": "Detroit Red Wings", "abbr": "DET" },
"away": { "id": "nhl_car", "name": "Carolina Hurricanes", "abbr": "CAR" },
"score": { "home": 0, "away": 3 },
"clock": { "period": 2, "display": "P2 3:52" }
}
],
"meta": { "request_id": "req_…", "count": 1, "credits_used": 1, "credits_remaining": 149870, "generated_at": "2026-10-14T23:33:43.548Z" }
}
The event object is the same one the odds endpoints return, so id joins straight to /v1/odds, /v1/best-lines and /v1/history. score is null whenever no score is known; it is never a placeholder 0–0. clock is set only while a game is live.
Status lifecycle
Events move from scheduled to live to final, and the id never changes along the way. If no source reports a result, a game is marked final once it has run past its sport's usual length and no source has quoted it for 10 minutes, and in any case 12 hours after the start. A game that is postponed or cancelled gets that status instead. start_time_tbd flags a placeholder kickoff, and when a game reached the feed under more than one id, the others are listed in alternate_ids and keep resolving to it.
Live scores API for game screens
For a scoreboard or a live odds screen, poll /v1/scores for the leagues you show. At 1 credit a call, polling one league every 30 seconds uses 2,880 credits a day, within Edge's 150,000 a month for a few leagues, and Sharp and Syndicate are unlimited. Live scores are on every paid plan, including Edge and Sharp, even though in-play odds are not: on those plans live games drop out of odds responses while their scores keep updating.
On Syndicate, the WebSocket stream pushes an event message whenever a game's status, score, clock or kickoff changes, next to the price deltas, so a live screen doesn't need to poll at all. The live odds API page covers in-play prices, and WebSocket odds API docs cover the message types.
Two event endpoints sit beside it. /v1/events (1 credit) lists scheduled and live games, with date_from and date_to for a schedule. /v1/events/{id} (1 credit) returns one game with its score, the sources pricing it and the market keys available.
Scores and odds on one game card
Because the ids match, a game card is a join on id. This fetches live scores and the best moneyline for the same league, 4 credits per refresh, and prints them together:
const headers = { Authorization: `Bearer ${process.env.PRECISEAPI_KEY}` };
const get = (path) => fetch(`https://api.preciseapi.com/v1/${path}`, { headers }).then((r) => r.json());
const [scores, lines] = await Promise.all([
get('scores?league=nba&status=live'),
get('best-lines?league=nba&markets=moneyline'),
]);
const moneyline = new Map(lines.data.map((e) => [e.id, e.markets.find((m) => m.key === 'moneyline')]));
for (const e of scores.data) {
const ml = moneyline.get(e.id);
const best = ml ? ml.outcomes.map((o) => `${o.name} ${o.best_price}`).join(' / ') : 'no in-play prices';
console.log(`${e.away.abbr} ${e.score?.away ?? '-'} @ ${e.home.abbr} ${e.score?.home ?? '-'} ${e.clock?.display ?? ''} ${best}`);
}
On Syndicate the prices are in-play. On Edge and Sharp, /v1/best-lines leaves games in progress out, so each live game prints its score without prices.
A results API for finished games
Finished games stay queryable through /v1/scores for four hours. That makes it a results API for settling and archiving, not a historical results database: if you need last season's finals, PreciseAPI doesn't have them. The reliable pattern is a job that runs every few minutes, asks for status=final,postponed,cancelled, and writes each new result into your own storage along with the event id.
Bet settlement API logic in your own code
Grading a full-game moneyline bet, point spread or over/under needs only the final score and the bet's line. This Python function settles moneylines, spreads and totals the way most books do:
import os
import requests
def grade(event, market, side, line=None):
"""Full-game moneyline, spread or total: won, lost, push, void, pending or no_score."""
if event["status"] in ("cancelled", "postponed"):
return "void"
if event["status"] != "final":
return "pending"
if not event["score"]:
return "no_score" # settle by hand
home, away = event["score"]["home"], event["score"]["away"]
if market == "moneyline":
winner = "home" if home > away else "away" if away > home else "draw"
if winner == side:
return "won"
return "push" if winner == "draw" and event["league"] != "soccer" else "lost"
if market == "spread":
margin = (home - away if side == "home" else away - home) + line
else: # total
margin = (home + away - line) * (1 if side == "over" else -1)
return "won" if margin > 0 else "lost" if margin < 0 else "push"
resp = requests.get(
"https://api.preciseapi.com/v1/scores",
params={"league": "nba", "status": "final,postponed,cancelled"},
headers={"Authorization": f"Bearer {os.environ['PRECISEAPI_KEY']}"},
timeout=10,
)
results = {e["id"]: e for e in resp.json()["data"]}
bet = {"event_id": "evt_1iazqk4srnb", "market": "spread", "side": "home", "line": -4.5}
event = results.get(bet["event_id"])
print(grade(event, bet["market"], bet["side"], bet["line"]) if event else "not final yet")
One /v1/scores call per league settles every open bet in it, which is cheaper than one /v1/events/{id} call per bet. Soccer moneylines are three-way, so a draw loses a home or away bet; in two-way sports a tied moneyline is a push.
Bet grading API: grade_bet over MCP
If you work in Claude, ChatGPT, Cursor or another AI client, the PreciseAPI MCP server can grade a bet for you. grade_bet takes an event id, a market (moneyline, spread or total), a selection (home, away, draw, over, under or a team name), the line, and optionally the price and stake. It returns won, lost, push, void or pending, a sentence explaining why, and the profit when you give a price and stake. Each call costs 1 credit.
{
"game": { "event_id": "evt_1iazqk4srnb", "league": "nba", "away": "San Antonio Spurs", "home": "Phoenix Suns", "starts": "Wed, Nov 11, 9:00 PM EST", "start_time": "2026-11-12T02:00:00.000Z", "status": "final", "score": { "San Antonio Spurs": 104, "Phoenix Suns": 112 } },
"bet": "Phoenix Suns -4.5 (spread, -110)",
"final_score": "San Antonio Spurs 104, Phoenix Suns 112",
"result": "won",
"detail": "Phoenix Suns -4.5: Phoenix Suns 112, opponent 104, covered by +3.5.",
"profit": 90.91,
"note": "Graded on the full-game final score in the feed (overtime included where the sport counts it). Check your book’s own settlement rules."
}
Ask "did Phoenix −4.5 cover last night?" and the client finds the game with find_games, then calls grade_bet. To list results, find_games with status final returns recent games with their final scores, 1 credit per call. The odds API MCP guide covers setup. Like the REST data, both tools only see games that finished within the last four hours or so.
What the score data doesn't include
Be clear about the limits before you build on it:
- No box scores or player stats. Player props can't be graded from this API.
- No period-by-period scores. The clock carries the current period, but there is no line score, so first-half, quarter and first-five-innings bets need another source of results.
- No historical archive. Results are kept for about four hours after a game ends.
- No score webhooks. Webhooks fire on line moves only. For status changes, poll
/v1/scoresor use the stream on Syndicate. - Not an official data feed. PreciseAPI isn't a league data provider. For disputes, the book's own settlement rules decide.
Plans and credit costs
/v1/scores, /v1/events and /v1/events/{id} cost 1 credit each on every paid plan, and grade_bet costs 1 credit over MCP. Edge ($49.99 a month) includes 150,000 credits; Sharp ($199.99) and Syndicate ($249.99) are unlimited, and only Syndicate adds in-play odds and the stream's live event messages. The free Sandbox has 50 credits for the dashboard chat but no API access, so a sports scores API integration starts on Edge. See odds API pricing.
Related pages
- Spread odds API and totals odds API guides cover grading spreads and totals, pushes included.
- Backtesting betting models shows how to archive results next to line history.
- The line movement API records the closing line to compare with each result.
- The odds API for betting apps use case puts scores and odds on one game card.
Frequently asked questions
Does the sports scores API include live scores on Edge?
Yes. /v1/scores returns live scores and the game clock on every paid plan. In-play odds are the part that needs Syndicate.
How long are final scores available?
About four hours after a game ends. Store results as games finish if you need them later.
Can PreciseAPI settle bets automatically?
Over MCP, grade_bet settles full-game moneyline, spread and total bets against the final score. Over REST, you grade in your own code from /v1/scores, as in the example above. Player props and period bets can't be graded from the feed.
Which leagues have scores?
Every event in the feed, across all 17 leagues, carries the same score and clock fields. A score appears once a source reports one and stays null until then, so check for null before you display or grade.
Are the event ids the same as in the odds?
Yes. Scores, events, odds, best lines and line history all use one event id, and it doesn't change when a game goes live.
What a score looks like
/v1/scores returns the event object the odds endpoints use, with status, score and clock. Status moves from scheduled to live to final, and the id never changes. score is null whenever no score is known, never a placeholder, and clock is set only while a game is live. Live scores are on every paid plan, including Edge and Sharp, where in-play odds are not. On Syndicate, the WebSocket stream also pushes score and status changes.
Grading and its limits
Finished games stay in /v1/scores for four hours, so a settlement job should store results as games end. Full-game moneylines, spreads and totals grade from the final score and the bet’s line, and over MCP the grade_bet tool returns won, lost, push, void or pending, with the profit when you give a price and stake. The feed has no box scores, player stats or period scores, so player props and first-half bets need another source of results.
Example request
GET /v1/scores?league=nhl&status=live
Endpoint
- GET /v1/scores: Live scores
What teams build with it
- Models & data science: Sports betting model data: market prices, implied probabilities and line history with stable ids, to train, backtest and run betting models and research.
- Sports apps & scoreboards: An odds API for betting apps and sports apps: real-time odds, live scores and deep links to each sportsbook, in the format your users read.
Related reading
- Spread Odds API Guide: Point Spread Lines, Prices, Alternates and Key Numbers: How point spreads are represented in odds data, the home-handicap sign convention, run lines, puck lines and handicaps, alternate spread ladders, key numbers, comparing spreads across books and separating line moves from price moves in history.
- Totals Odds API: Over/Under Game, Period and Team Totals Data: How over/under totals are modeled in odds data, game totals by period, team totals with their team object, alternate total ladders, consistency checks between them, comparing totals across books, grading pushes and reading totals history.
- Moneyline Odds API: Pull, Compare and Convert Moneylines in Code: How moneylines are modeled in an odds API, two-way and three-way markets, periods, pulling them across books, converting between American, decimal and probability, measuring margin and charting moneyline history.
More products
- Line movement API: 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.
- Game odds API: Betting odds API for moneylines, spreads and totals from 36 sources, for every period, plus alternate lines and team totals in one normalized schema.
- Player props API: Player props API with real-time prop odds from every sportsbook and DFS pick’em app: points, rebounds, passing yards, strikeouts and more, on stable player ids.
- Live odds API: Live odds API with in-play prices pushed in under 500 ms over WebSocket on Syndicate, plus live scores, the game clock and automatic suspension of stale prices.
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.