Live Board

free  live 📅
Requests today
Total requests
Events in feed
Live now
Markets / event
300+
Live refresh
15s
⚡ Your requests · last 14 days

Feed vitals

LIVE  board refresh15 s
LINE  pre-match crawl4 m
DEEP  market sync2 m
API  p95 latency84 ms

Live matches

MatchScore1X2Updated
Loading…

⚡ Steam moves · last 60m

≥3% swing
Loading…

⏱ Starting soon

next kick-offs
Loading…

◍ Coverage

top sports
Loading…

API keys

⚠ Store this key securely — it will not be shown again.
LabelKeyStatusRate limitTodayTotalLast used
Loading…

Your plan

Loading…

Quick start

curl -H "X-Api-Key: YOUR_KEY" \
  https://your-host/api/v1/events?live=1

// real-time push
const es = new EventSource('/api/v1/stream?api_key=YOUR_KEY');
es.addEventListener('live', (e) => {
  const { events } = JSON.parse(e.data);
});
Full reference in Documentation.

API Documentation

Pre-match & live odds scraped continuously from 1xbet.ng, with normalized markets. All responses are JSON.

Authentication

Pass your API key in the X-Api-Key header (or as a Bearer token). Keys are created under API Keys. Limits depend on your plan:

PlanRate limitDaily quotaKeys
free60 req/min20,0002
pro300 req/min500,0005
enterprise1000 req/min5,000,00020
curl -H "X-Api-Key: sb_live_xxxxxxxx" \
  "https://your-host/api/v1/events?live=1"

Endpoints

GET /api/v1/sports
GET /api/v1/events
GET /api/v1/events/:id
GET /api/v1/events/:id/history
GET /api/v1/events/:id/opening
GET /api/v1/events/:id/closing
GET /api/v1/events/:id/compile — odds compilation toolkit
GET /api/v1/live
GET /api/v1/stream — Server-Sent Events
GET /api/v1/status — no key required

GET /api/v1/sports

List all sports with current event and championship counts.

{
  "data": [
    { "id": 1, "name": "Football", "events": 2370, "championships": 387 }
  ]
}

GET /api/v1/events

Paginated event list with odds markets. Supports filtering and delta sync.

ParamDescription
live1 only live, 0 only pre-match
sport_idFilter by sport (see /sports)
leagueSubstring match on league name
updated_afterUnix ms — delta sync: only events updated after this timestamp
markets0 to exclude odds (smaller payloads)
page, limitPagination (limit ≤ 500, default 100)
{
  "page": 1, "limit": 100, "total": 2381, "pages": 24,
  "data": [{
    "id": 739473824,
    "sport_id": 1, "sport": "Football",
    "league_id": 122768, "league": "England. Premier League",
    "home": "Arsenal", "away": "Chelsea",
    "start": 1786485600, "start_iso": "2026-08-10T14:00:00.000Z",
    "live": false, "state": null, "score": null,
    "markets": [
      { "market": "1x2", "selection": "1", "line": null, "price": 2.02 },
      { "market": "total", "selection": "over", "line": 2.5, "price": 1.85 },
      { "market": "handicap", "selection": "1", "line": -0.5, "price": 2.02 }
    ],
    "updated_at": 1786480000000
  }]
}

GET /api/v1/live

Live events with scores and in-play markets, ordered by freshness.

{
  "data": [{
    "id": 740111222, "sport": "Football",
    "home": "Real Madrid", "away": "Barcelona",
    "live": true, "state": "1st half",
    "score": { "home": 1, "away": 0 },
    "markets": [ /* in-play odds */ ]
  }]
}

GET /api/v1/events/:id/history

Odds movement timeline for an event — every price change we observed, oldest first. Filter with market, cap with limit (≤ 5000). Retained for 7 days.

{
  "data": [
    { "market": "1x2", "selection": "1", "line": null, "price": 2.02, "ts": 1786480000000 },
    { "market": "1x2", "selection": "1", "line": null, "price": 1.95, "ts": 1786480900000 }
  ]
}

GET /api/v1/events/:id/opening

The opening line — first-seen odds for every market of the event, with the timestamp we first observed them. Derived from the same 7-day store as /history.

{
  "data": [
    { "market": "1x2", "selection": "1", "line": null, "opening_price": 2.10, "opening_ts": 1786470000000 }
  ]
}

GET /api/v1/events/:id/closing

The closing line — one full-market snapshot captured shortly before kickoff (~15 min out), kept permanently. This is the reference price for closing-line value (CLV) analytics. Returns 404 until the event’s snapshot is captured.

{
  "captured_at": 1786484100000,
  "data": [
    { "market": "1x2", "selection": "1", "line": null, "closing_price": 2.04 },
    { "market": "total", "selection": "over", "line": 2.5, "closing_price": 1.83 }
  ]
}

GET /api/v1/events/:id/compile — odds compilation toolkit

A pricing desk in one call for sportsbooks: the current line with opening price, drift and the captured closing price, no-vig fair probabilities (three devig methods), and ready-to-publish odds with your chosen margin re-applied (three margin methods) — each with clv_pct, the edge of your compiled price over the market close.

ParamDescription
marketMarket name to compile (default 1x2)
marginTarget margin % for compiled odds, 0–30 (default 5)
devigFair-prob method used as compilation base: shin (default) | proportional | power
lineFor lined markets (totals/handicaps); defaults to the median available line
{
  "event": { "id": 739473824, "home": "Arsenal", "away": "Chelsea", "live": false },
  "market": "1x2", "line": null, "margin_pct": 5, "devig": "shin",
  "overround_pct": 5.4,
  "closing_captured_at": 1786484100000,
  "raw": [
    { "selection": "1", "price": 2.02, "opening_price": 2.10, "opening_ts": 1786470000000, "drift_pct": -3.81, "closing_price": 2.04 },
    { "selection": "x", "price": 3.60, "opening_price": 3.50, "opening_ts": 1786470000000, "drift_pct": 2.86, "closing_price": 3.55 },
    { "selection": "2", "price": 3.90, "opening_price": 3.80, "opening_ts": 1786470000000, "drift_pct": 2.63, "closing_price": 3.95 }
  ],
  "fair": {
    "shin":         [{ "selection": "1", "probability": 0.4621, "odds": 2.16 }, /* x, 2 */ ],
    "proportional": [{ "selection": "1", "probability": 0.4623, "odds": 2.16 }, /* x, 2 */ ],
    "power":        [{ "selection": "1", "probability": 0.4618, "odds": 2.17 }, /* x, 2 */ ]
  },
  "compiled": {
    "proportional":       [{ "selection": "1", "implied_pct": 48.54, "odds": 2.06, "clv_pct": 0.98 }, /* x, 2 */ ],
    "power":              [{ "selection": "1", "implied_pct": 48.60, "odds": 2.06, "clv_pct": 0.98 }, /* x, 2 */ ],
    "favourite_longshot": [{ "selection": "1", "implied_pct": 48.30, "odds": 2.07, "clv_pct": 1.47 }, /* x, 2 */ ]
  }
}

Devig methods: proportional normalizes implieds; power raises them to k (Σπ^k = 1); shin solves Shin’s (1993) z-parameter and is most robust to favourite–longshot bias. Margin methods re-apply your vig: proportional equal margin on every selection, power multiplicative, favourite_longshot shifts half the margin onto longshots. clv_pct = (your odds / closing price − 1) × 100 — positive means your published price beats the market close.

GET /api/v1/stream — real-time push

Server-Sent Events stream. On connect you receive a snapshot event with all live events; afterwards a live event is pushed whenever any score or match state changes. Keep-alive ping events arrive every 25s. Browser EventSource cannot set headers, so pass the key as ?api_key= (max 3 concurrent connections per key).

const es = new EventSource('/api/v1/stream?api_key=YOUR_KEY');
es.addEventListener('snapshot', (e) => renderAll(JSON.parse(e.data).events));
es.addEventListener('live', (e) => applyDiff(JSON.parse(e.data).events));

Market types

Odds are normalized to these market names (unknown upstream types are passed through as type_<code>):

1x2, double_chance, handicap, total, total_odd_even,
individual_total_1, individual_total_2, team_total_1, team_total_2,
handicap_1x2, goal_total, double_chance_total, both_teams_to_score,
winner, race_to

Each market entry has market, selection, optional line (handicap/total value), upstream group and price.

Upcoming fixtures in the deep-coverage sports (football, ice hockey, basketball, tennis, baseball, volleyball, table tennis, american football, esports, cricket) are additionally enriched with full market depth (hundreds of markets per event, refreshed every few minutes). Events carrying deep data have "deep_markets": true.

Errors

401  missing or invalid API key
403  key disabled
404  resource not found
429  rate limit or daily quota exceeded (Retry-After header set)

Integration tips

• Prefer /api/v1/stream for live score updates — it pushes diffs instead of requiring polling.
• Poll /api/v1/live every 15–30 seconds as a fallback/sync anchor.
• Use updated_after on /events for cheap incremental pre-match syncs.
• Track line movement via /events/:id/history.
start is unix seconds; updated_at is unix milliseconds.
• Events that finish/drop off the upstream feed are removed automatically within hours.