TL;DR

We’ve shipped a major-version upgrade to the AnySport football data API. In short: we now serve more data, and our real-time push covers far more of it.

  • Data scale: odds markets are now standardized into a market_code dictionary (63 pre-match, 499 live), and we’ve added a batch of new endpoints — seasons, coaches, injuries, match details, live match situation, match events, and a relative upcoming-fixtures window.
  • Real-time push: the old WebSocket could only deliver live scores. After this upgrade, you can subscribe over WebSocket to scores, match situation, pre-match odds, and live odds.

This release also changes the base URL, the authentication method, and the ID scheme, so existing v1 users need to update their code per the migration guide below — it is not a drop-in, painless swap. We’ve written down every gotcha in this post.

📌 The docs moved too. The new docs are at docs.anysport.io; the old v1 docs are archived at docsv1.anysport.io. Every endpoint, field, and code below refers to the new version.

1. What’s New at a Glance

Here’s the full picture in one table (🔴 = a breaking change for v1 users that requires code changes):

Aspectv1 (old)New
REST base URLhttps://api.anysport.io/v1https://data.anysport.io/v1/soccer🔴
AuthenticationX-API-Key header or ?api_key= query paramapikey header only (lowercase, no X-); query params not supported🔴
Entity IDsplain integers (match_id: 1234567, league_id: 148)semantic prefixed strings (as_ / asl_ / ast_ …)🔴
Odds data modelhuman-readable market_name ("1X2"), no full catalogstandardized market_code dictionary (match_winner)🔴
Pre-match marketsa handful of common markets63 market_codes, fully cataloged⬆️
Live (in-play) marketssome common markets, no unified code dictionary499 market_codes, full dictionary⬆️
WebSocket dataa single livescore_update streamfour streams: scores / situation / pre-match odds / live odds⬆️🔴
WebSocket protocolfilter via league_id/match_id in the URLsubscribe protocol: send a subscription code + heartbeat🔴
Response envelopesuccess / data / metasuccess / data / meta / traceId⬆️
New endpoints—seasons, coaches, injuries, match details, live situation, match events, upcoming-fixtures window⬆️

Two themes run through this release: breadth of data and real-time reach over WebSocket. Let’s take them one at a time.

2. Upgrade #1: Bigger, Cleaner Data Coverage

2.1 Odds: a Standardized market_code Dictionary

In v1, each odds market was represented by a human-readable market_name string with no authoritative catalog — you had to guess and string-match your way through it:

// v1: GET https://api.anysport.io/v1/odds?match_id=1234567
{
  "data": [{
    "match_id": 1234567,
    "bookmakers": [{
      "bookmaker_name": "bet365",
      "markets": [
        { "market_name": "1X2", "odds": [ {"value":"Home","odd":1.38}, ... ] },
        { "market_name": "Over/Under", "odds": [ {"value":"Over","odd":2.0,"handicap":"2.5"}, ... ] }
      ]
    }]
  }]
}

The new version fully standardizes markets into a market_code enum dictionary and publishes the complete catalog — enumerable, easy to cross-reference, and easy to build a mapping table against:

  • Pre-match odds GET /odds/prematch: 63 market_codes — from match_winner, asian_handicap, and goals_over_under to double_chance, ht_ft_double, odd_even, and more. Essentially everything a typical pre-match analysis page needs.
  • Live odds GET /odds/live: a full dictionary of 499 market_codes — European (3-way) handicap, Asian handicap (including 1st/2nd half), over/under, full-match and half corners, next goal, remaining-time lines, and so on. A single in-play match typically has dozens of active markets updating at once.

For v1 users, this means your old logic that string-matched on market_name needs to switch to routing on market_code (see the migration in Section 4).

⚠️ market_code is an open enum and will keep growing. We’ll continue adding new markets, so your client should degrade gracefully on unknown market_codes rather than throw — skip or pass them through untouched. That way your parsing layer won’t break when we ship new markets.

A few long-standing odds gotchas still apply:

⚠️ Pre-match and live are two independent streams with different label systems. For the same home/draw/away outcome, pre-match uses Home/Draw/Away while live uses 1/X/2 — if you want one parser for both streams, you must map between them. The handicap value also lives in different places (embedded in the option name for pre-match, in the standalone markets[].handicap field for live), and after full time a live match’s markets may shrink to an empty array [].

2.2 A Batch of New Endpoints

Beyond odds, this release fills in a lot of data endpoints:

  • Seasons
  • Coaches
  • Injuries
  • Match details
  • Live match situation
  • Upcoming-fixtures window

Together with the existing fixtures, scores, lineups, standings, top scorers, and head-to-head endpoints, that rounds out a complete football data pipeline.

3. Upgrade #2: WebSocket Expands to Four Subscribable Streams

This is the part we’re most excited about — and the biggest change.

The old WebSocket had a single stream. You connected to wss://api.anysport.io/v1/ws/live?api_key=KEY&league_id=148 and the server pushed a continuous feed of livescore_update messages. It could power a scoreboard, but it couldn’t deliver odds, had no dedicated technical-stats stream, and could only be filtered via league_id/match_id in the URL:

// v1: the only push type
{ "type": "livescore_update", "data": [ { "match_id": 1234567, "score": "2-1", "minute": 67, ... } ] }

The new version splits it apart and expands it dramatically. Over a single long-lived connection, you can subscribe to any combination of the 4 data products below, each with its own subscription code and push type, independently of the others:

Data productSubscribe codeSub confirmedUnsubscribe codePush type
Scores202002020121200score_update
Situation (event feed + technical stats)200002000121000situation_update
Live odds201002010121100odds_live_update
Pre-match odds203002030121300odds_prematch_update

The two most tangible changes: odds can be pushed over WebSocket for the first time (both pre-match and live), and the match situation becomes its own richest stream (complete events — goals, cards, substitutions — plus stats_json technical stats and ball_xy ball coordinates). A live betting page that used to stitch together three separate mechanisms — “WebSocket for scores + polling for odds + polling for events” — is now handled by one connection and one match_id.

3.1 Establishing a Connection

The new handshake URL (note the domain is data., not the old api.):

wss://data.anysport.io/v1/ws/live?api_key=YOUR_API_KEY

A successful handshake returns a connected message. At this point no data is pushed yet — pushes start only after you send a subscription message:

{ "type": "connected", "message": "WebSocket connected. Send subscribe message to receive data.", "timestamp": "2026-07-13T08:00:00.000Z" }

3.2 Subscribe to Scores (20200)

Filters (match_id/league_id/country_id) go inside the subscription message’s data, not the URL. A match_id of null means subscribe to everything allowed by your plan/filters:

{ "code": 20200, "trace": "score-sub-001", "data": { "match_id": null } }

Push (score_update; the score semantics match the REST /livescore endpoint exactly):

{
  "type": "score_update",
  "data": {
    "type": "score", "match_id": "as_3b37c382...", "home_team": "Argentina", "away_team": "Switzerland",
    "phase": "2H", "minute": 67, "home_score": 2, "away_score": 1, "ht_score": "1-0", "reg_score": "2-1"
  },
  "timestamp": "2026-07-13T15:47:01.250Z"
}

3.3 Subscribe to Live Situation (20000)

{ "code": 20000, "trace": "situation-sub-001", "data": { "match_id": "as_3b37c382..." } }

Push (situation_update; includes the event feed, technical stats, and ball coordinates):

{
  "type": "situation_update",
  "data": {
    "type": "situation", "match_id": "as_3b37c382...", "status": "live", "minute": 67,
    "ball_xy": "0.52,0.48", "events_json": {}, "stats_json": {}
  },
  "timestamp": "2026-07-13T15:47:01.250Z"
}

3.4 Subscribe to Live Odds (20100) / Pre-match Odds (20300)

{ "code": 20100, "trace": "live-odds-sub-001", "data": { "match_id": "as_3b37c382..." } }

Push (odds_live_update):

{
  "type": "odds_live_update",
  "data": {
    "type": "odds", "match_id": "as_3b37c382...", "phase": "live", "main_market": "1X2",
    "home_odd": "2.10", "draw_odd": "3.40", "away_odd": "3.20", "markets_json": {}
  },
  "timestamp": "2026-07-13T15:47:01.250Z"
}

For pre-match odds, just switch the code to 20300; the push type is odds_prematch_update and the data structure is identical to live odds, differing only in that data.phase is prematch.

⚠️ Subscription state does not persist across connections. After a reconnect you must re-send your subscription messages. Send a heartbeat every 30 seconds (code: 20010) or the server will drop you on timeout. The 4xxxx series (e.g. subscription failure 40301) are recoverable client-side errors that do not close the connection — fix the message format, fields, or plan permission and retry.

4. Migration Checklist for v1 Users (Important)

This release has breaking changes, so existing integrations need the steps below. It comes down to three things: URL, authentication, and IDs.

4.1 Authentication & URL (required)

- # v1
- GET https://api.anysport.io/v1/odds?match_id=1234567
- X-API-Key: YOUR_API_KEY                       # or ?api_key=YOUR_API_KEY

+ # New
+ GET https://data.anysport.io/v1/soccer/odds/prematch?match_id=as_3b37c382...
+ apikey: YOUR_API_KEY                           # this header only; passing the key as a query param always returns 401
  • Base URL: api.anysport.io/v1 → data.anysport.io/v1/soccer (note the added /soccer segment).
  • Auth header: X-API-Key (or ?api_key=) → apikey, the lowercase header, only. Still using X-API-Key, or putting the key in the URL, returns 401 UNAUTHORIZED.

4.2 IDs Change from Integers to Prefixed Strings (required)

v1 match_id/league_id/team_id were plain integers; the new version makes them all semantic prefixed strings:

PrefixEntityExample
as_Match (unified across all endpoints)as_3b37c382f39a4235aa93705f053b2da4
asl_Leagueasl_62db9cfc3ebf4b87a44570b16668b23e
ast_Teamast_9137ee449e3b40a68149ca319373adaf
asx_ asp_ asc_Country / Player / Coach—

Any database column that stores an ID, and every place you build a URL, needs to move from integer to string. The good news: the same match_id runs through fixtures, scores, situation, odds, and WebSocket, identical everywhere — no ID mapping table required.

4.3 Parse Odds by market_code

Replace logic that string-matched on market_name ("1X2", "Over/Under") with routing on market_code (match_winner, goals_over_under), and degrade gracefully on unknown codes. See the pre-match and live market directories in the new docs for the full catalog.

4.4 Switch WebSocket to the Subscribe Protocol

  • Change the URL to wss://data.anysport.io/v1/ws/live.
  • Move filters from URL params to a subscription message (code + data).
  • Subscribe to whichever codes you need, and add the 30-second heartbeat plus reconnect-and-resubscribe logic.

5. Which Plan Do These Features Require?

PlanPrice (USDT/month)OddsWebSocket
Free trial (7 days)0❌❌
Basic99❌❌
Pro199✅ Pre-match odds❌
Premium399✅ Pre-match + live✅ (all four data streams)

6. Summary

This upgrade pushes two of AnySport’s core capabilities forward:

  • Data breadth: odds standardized into a market_code dictionary — 63 pre-match plus 499 live — along with a batch of new endpoints (seasons, coaches, injuries, situation, events, and more).
  • Full real-time coverage: WebSocket goes from a single live-scores stream to four independently subscribable streams — scores, situation, pre-match odds, and live odds — with odds on WebSocket for the first time, all over one connection and one match_id.

👉 Sign up now at anysport.io and start a free 7-day trial — get the scores stream running first, then upgrade to odds and WebSocket as you need them.