API reference

16 operations, generated from the contract the API serves.

Base URL: https://api.sockodds.com/v1. Send your key as Authorization: Bearer; keep it on your server, out of browser code and out of URLs. Start with the quickstart if this is your first request.

Responses use { data, meta, links }. Follow links.next unchanged to continue a list. Errors use application/problem+json. Example identities and dates below are illustrative; use the values your own responses return.

Try live requests from the API playground in your account, or get the AI starter context. The OpenAPI contract is the source of this page and of the Postman collection.

GET/sports

Operation listSports · Catalogue

Lists sports.

curl -sS "https://api.sockodds.com/v1/sports" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/sports", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/sports",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "key": "australian_football",
      "name": "Australian football",
      "participants": "teams"
    },
    {
      "key": "rugby_league",
      "name": "Rugby league",
      "participants": "teams"
    },
    {
      "key": "rugby_union",
      "name": "Rugby union",
      "participants": "teams"
    },
    {
      "key": "soccer",
      "name": "Soccer",
      "participants": "teams"
    },
    {
      "key": "basketball",
      "name": "Basketball",
      "participants": "teams"
    },
    {
      "key": "american_football",
      "name": "American football",
      "participants": "teams"
    },
    {
      "key": "baseball",
      "name": "Baseball",
      "participants": "teams"
    },
    {
      "key": "ice_hockey",
      "name": "Ice hockey",
      "participants": "teams"
    },
    {
      "key": "tennis",
      "name": "Tennis",
      "participants": "competitors"
    },
    {
      "key": "mma",
      "name": "Mixed martial arts",
      "participants": "competitors"
    },
    {
      "key": "cricket",
      "name": "Cricket",
      "participants": "teams"
    },
    {
      "key": "motorsport",
      "name": "Motorsport",
      "participants": "competitors"
    },
    {
      "key": "esports",
      "name": "Esports",
      "participants": "teams"
    }
  ],
  "meta": {
    "count": 13,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/leagues

Operation listLeagues · Catalogue

Lists leagues.

ParameterInRequiredTypeMeaning
sportqueryNoKey (string)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/leagues?sport=rugby_league" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/leagues?sport=rugby_league", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/leagues?sport=rugby_league",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "key": "nrl",
      "name": "NRL",
      "sport": "rugby_league",
      "region": "au",
      "periods": [
        "full",
        "regulation",
        "half_1",
        "half_2"
      ]
    },
    {
      "key": "nrlw",
      "name": "NRL Women's",
      "sport": "rugby_league",
      "region": "au",
      "periods": [
        "full",
        "regulation",
        "half_1",
        "half_2"
      ]
    },
    {
      "key": "rlwc",
      "name": "Rugby League World Cup",
      "sport": "rugby_league",
      "region": "intl",
      "periods": [
        "full",
        "regulation",
        "half_1",
        "half_2"
      ]
    },
    {
      "key": "rlwcw",
      "name": "Rugby League World Cup Women's",
      "sport": "rugby_league",
      "region": "intl",
      "periods": [
        "full",
        "regulation",
        "half_1",
        "half_2"
      ]
    }
  ],
  "meta": {
    "count": 4,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/bookmakers

Operation listBookmakers · Catalogue

Lists bookmakers.

ParameterInRequiredTypeMeaning
regionsqueryNostringComma-separated bookmaker regions, at most 20.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/bookmakers?regions=au&limit=3" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/bookmakers?regions=au&limit=3", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/bookmakers?regions=au&limit=3",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "key": "bearbet",
      "name": "BearBet",
      "kind": "sportsbook",
      "regions": [
        "au"
      ]
    },
    {
      "key": "bet365",
      "name": "bet365",
      "kind": "sportsbook",
      "regions": [
        "au"
      ]
    },
    {
      "key": "betblitz",
      "name": "BetBlitz",
      "kind": "sportsbook",
      "regions": [
        "au"
      ]
    }
  ],
  "meta": {
    "count": 3,
    "cursor": "eyJuIjozLCJmIjoiZTUzY2IxODA0YzI4NTg2ZCJ9"
  },
  "links": {
    "next": "https://api.sockodds.com/v1/bookmakers?regions=au&limit=3&cursor=eyJuIjozLCJmIjoiZTUzY2IxODA0YzI4NTg2ZCJ9"
  }
}

GET/markets

Operation listMarkets · Catalogue

Markets and the sides each offers. With league, only the markets offered in that league's sport, and only the role sides that sport uses (winner and handicap are home and away in team sports, competitor_1 and competitor_2 in tennis; winner is also offered in UFC).

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/markets?league=rlwc&limit=2" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/markets?league=rlwc&limit=2", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/markets?league=rlwc&limit=2",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "key": "winner",
      "name": "Winner",
      "subject": "event",
      "bet": "winner",
      "stat": null,
      "has_line": false,
      "sides": [
        "home",
        "away"
      ],
      "sports": [
        "australian_football",
        "rugby_league",
        "rugby_union",
        "basketball",
        "american_football",
        "baseball",
        "ice_hockey",
        "tennis",
        "mma",
        "cricket",
        "esports"
      ],
      "periods": [
        "full",
        "half_1",
        "half_2",
        "quarter_1",
        "quarter_2",
        "quarter_3",
        "quarter_4",
        "innings_1_to_5",
        "half_2_ot",
        "period_1",
        "period_2",
        "period_3",
        "set_1",
        "set_2",
        "set_3",
        "set_4",
        "set_5",
        "map_1",
        "map_2",
        "map_3",
        "map_4",
        "map_5"
      ]
    },
    {
      "key": "result",
      "name": "Result (with the draw)",
      "subject": "event",
      "bet": "result",
      "stat": null,
      "has_line": false,
      "sides": [
        "home",
        "draw",
        "away"
      ],
      "sports": [
        "american_football",
        "soccer",
        "rugby_league",
        "rugby_union",
        "ice_hockey",
        "cricket",
        "baseball"
      ],
      "periods": [
        "full",
        "regulation",
        "half_1",
        "half_2",
        "period_1",
        "period_2",
        "period_3",
        "quarter_1",
        "quarter_2",
        "quarter_3",
        "quarter_4",
        "inning_1",
        "innings_1_to_5"
      ]
    }
  ],
  "meta": {
    "count": 2,
    "cursor": "eyJuIjoyLCJmIjoiNDYxMmFlY2Y5ZGMzY2Y5NCJ9"
  },
  "links": {
    "next": "https://api.sockodds.com/v1/markets?league=rlwc&limit=2&cursor=eyJuIjoyLCJmIjoiNDYxMmFlY2Y5ZGMzY2Y5NCJ9"
  }
}

GET/teams

Operation listTeams · Identity

Lists teams.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/teams?league=rlwc&limit=2" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/teams?league=rlwc&limit=2", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/teams?league=rlwc&limit=2",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "key": "australia_rugby_league",
      "name": "Australia",
      "sport": "rugby_league",
      "leagues": [
        "rlwc"
      ]
    },
    {
      "key": "new_zealand_rugby_league",
      "name": "New Zealand",
      "sport": "rugby_league",
      "leagues": [
        "rlwc"
      ]
    }
  ],
  "meta": {
    "count": 2,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/players

Operation listPlayers · Identity

Lists players.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
teamqueryNoKey (string)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/players?league=rlwc&team=australia_rugby_league&limit=2" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/players?league=rlwc&team=australia_rugby_league&limit=2", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/players?league=rlwc&team=australia_rugby_league&limit=2",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "id": "pl_000ckk0qrcd5",
      "name": "Blayke Brailey",
      "sport": "rugby_league",
      "team": {
        "key": "australia_rugby_league",
        "name": "Australia"
      }
    },
    {
      "id": "pl_000ckk0v7atp",
      "name": "Bradman Best",
      "sport": "rugby_league",
      "team": {
        "key": "australia_rugby_league",
        "name": "Australia"
      }
    }
  ],
  "meta": {
    "count": 2,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/events

Operation listEvents · Identity

Lists events.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
starts_afterqueryNostring (date-time)UTC date and time. With neither starts_after nor starts_before, the list starts 48 hours ago (live and upcoming games plus the last two days), and international cricket Tests (league cricket) are listed for six days from their start; name a window to list older games.
starts_beforequeryNostring (date-time)UTC date and time. Give starts_after, starts_before or both to list games outside the default window (from 48 hours ago; six days for cricket Tests).
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/events?league=rlwc" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/events?league=rlwc", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events?league=rlwc",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "id": "ev_000ckk0zrx33",
      "name": "Australia v New Zealand",
      "league": {
        "key": "rlwc",
        "name": "Rugby League World Cup"
      },
      "scheduled_start": "2026-10-15T09:05:00.000Z",
      "status": "scheduled",
      "participants": [
        {
          "role": "away",
          "identity": {
            "key": "new_zealand_rugby_league",
            "name": "New Zealand"
          }
        },
        {
          "role": "home",
          "identity": {
            "key": "australia_rugby_league",
            "name": "Australia"
          }
        }
      ]
    }
  ],
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/events/lookup

Operation lookupEvents · Identity

Find our event from an official event id: ESPN's event id, the AFL's match id (CD_M and digits) for AFLW, or the NRL's match id (digits) for the Rugby League World Cup. Send ref for one event, or refs for up to 100 at once. With ref, the response is the event, or 404 when no event carries that id. With refs, the response lists the ids that matched, in the order sent, each with its event; ids that match nothing are left out. A merged event returns the event it was merged into. Only official sources can be looked up, never a bookmaker's listing id. Each event returned counts as one object towards your allowance, like an event read.

ParameterInRequiredTypeMeaning
sourcequeryYesOfficialSource (one of espn, afl, nrl)Who issued the id: espn, afl for AFLW match ids, or nrl for Rugby League World Cup match ids.
refqueryNoOfficialRef (string)One official event id. Use this or refs, not both.
refsqueryNostringComma-separated official event ids, at most 100. Use this or ref, not both.
curl -sS "https://api.sockodds.com/v1/events/lookup?source=nrl&ref=20261310110" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/events/lookup?source=nrl&ref=20261310110", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events/lookup?source=nrl&ref=20261310110",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": {
    "id": "ev_000ckk0zrx33",
    "name": "Australia v New Zealand",
    "league": {
      "key": "rlwc",
      "name": "Rugby League World Cup"
    },
    "scheduled_start": "2026-10-15T09:05:00.000Z",
    "status": "scheduled",
    "participants": [
      {
        "role": "away",
        "identity": {
          "key": "new_zealand_rugby_league",
          "name": "New Zealand"
        }
      },
      {
        "role": "home",
        "identity": {
          "key": "australia_rugby_league",
          "name": "Australia"
        }
      }
    ]
  },
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/events/{event_id}

Operation getEvent · Identity

Returns event.

ParameterInRequiredTypeMeaning
event_idpathYesEventId (string)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/events/ev_000ckk0zrx33" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/events/ev_000ckk0zrx33", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events/ev_000ckk0zrx33",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": {
    "id": "ev_000ckk0zrx33",
    "name": "Australia v New Zealand",
    "league": {
      "key": "rlwc",
      "name": "Rugby League World Cup"
    },
    "scheduled_start": "2026-10-15T09:05:00.000Z",
    "status": "scheduled",
    "participants": [
      {
        "role": "away",
        "identity": {
          "key": "new_zealand_rugby_league",
          "name": "New Zealand"
        }
      },
      {
        "role": "home",
        "identity": {
          "key": "australia_rugby_league",
          "name": "Australia"
        }
      }
    ]
  },
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/events/{event_id}/odds

Operation getEventOdds · Prices

Current prices for one event, grouped by market: each market and outcome appears once, and each outcome lists every bookmaker's price in prices, best price first. Markets come in catalogue order, then period, subject and line; outcomes in the market's side order. Use group_by=bookmaker for one block per bookmaker instead (the shape v1 launched with). Each price counts as one object towards your allowance, plus one for the event, in either shape.

ParameterInRequiredTypeMeaning
event_idpathYesEventId (string)See the OpenAPI schema for allowed values.
marketsqueryNostringComma-separated market keys, at most 20.
regionsqueryNostringComma-separated bookmaker regions, at most 20.
bookmakersqueryNostringComma-separated bookmaker keys, at most 20.
alternatesqueryNoboolean (default false)See the OpenAPI schema for allowed values.
group_byqueryNostring (one of market, bookmaker; default market)How prices are grouped. market (the default) lists each market and outcome once, with every bookmaker's price under the outcome in prices, best price first. bookmaker lists each bookmaker with its own copy of the markets, the shape v1 launched with.
non_participantqueryNostringComma-separated non-participation rules (void, loses, under, fair_price). Keeps only player-market prices whose bookmaker settles a player who takes no part by one of these rules; prices on every other market are unaffected. For example non_participant=void keeps only player prices that are refunded when the player does not play.
snapshotsqueryNostring (one of opening, closing, opening,closing)Pro and Internal only. Adds opening, closing or both, as requested, to each price, from that bookmaker's own quotes observed strictly before a cutoff (a quote stamped exactly at the cutoff does not count). For every sport but MMA the cutoff is the event's scheduled_start, so in-play quotes never count. For an MMA bout, whose scheduled_start is its card segment's start, the cutoff once the bout has been observed live or final (first at F) is the last poll that still showed it scheduled before F, but never earlier than the earlier of scheduled_start and F; a bout never observed live or final uses scheduled_start.
curl -sS "https://api.sockodds.com/v1/events/ev_000ckk0zrx33/odds?markets=winner&bookmakers=sportsbet" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/events/ev_000ckk0zrx33/odds?markets=winner&bookmakers=sportsbet", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events/ev_000ckk0zrx33/odds?markets=winner&bookmakers=sportsbet",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": {
    "id": "ev_000ckk0zrx33",
    "name": "Australia v New Zealand",
    "league": {
      "key": "rlwc",
      "name": "Rugby League World Cup"
    },
    "scheduled_start": "2026-10-15T09:05:00.000Z",
    "status": "scheduled",
    "participants": [
      {
        "role": "away",
        "identity": {
          "key": "new_zealand_rugby_league",
          "name": "New Zealand"
        }
      },
      {
        "role": "home",
        "identity": {
          "key": "australia_rugby_league",
          "name": "Australia"
        }
      }
    ],
    "markets": [
      {
        "id": "mk_pz0msgze2rqwwktb",
        "key": "winner",
        "name": "Winner",
        "period": "full",
        "subject": null,
        "alternate": false,
        "outcomes": [
          {
            "id": "oc_nncgcssmzjhyt5pe",
            "name": "Australia",
            "side": "home",
            "line": null,
            "prices": [
              {
                "bookmaker": "sportsbet",
                "decimal_odds": 1.72,
                "implied_probability": 0.581395,
                "available": true,
                "observed_at": "2026-10-15T07:58:00.000Z"
              }
            ]
          },
          {
            "id": "oc_cwsr1gda0qcgf03j",
            "name": "New Zealand",
            "side": "away",
            "line": null,
            "prices": [
              {
                "bookmaker": "sportsbet",
                "decimal_odds": 2.12,
                "implied_probability": 0.471698,
                "available": true,
                "observed_at": "2026-10-15T07:58:00.000Z"
              }
            ]
          }
        ]
      }
    ]
  },
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/odds

Operation listOdds · Prices

Current prices for a page of events (25 by default, up to 100), grouped by market as on /events/{event_id}/odds unless group_by=bookmaker. Pages follow events; a cursor works only with the filters and grouping it was issued for, so follow links.next. Filters apply to prices before grouping: an outcome or market with no matching price is left out, and an event with none has an empty markets list. Each price counts as one object towards your allowance, plus one per event.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
marketsqueryNostringComma-separated market keys, at most 20.
regionsqueryNostringComma-separated bookmaker regions, at most 20.
bookmakersqueryNostringComma-separated bookmaker keys, at most 20.
starts_afterqueryNostring (date-time)UTC date and time. With neither starts_after nor starts_before, the list starts 48 hours ago (live and upcoming games plus the last two days), and international cricket Tests (league cricket) are listed for six days from their start; name a window to list older games.
starts_beforequeryNostring (date-time)UTC date and time. Give starts_after, starts_before or both to list games outside the default window (from 48 hours ago; six days for cricket Tests).
alternatesqueryNoboolean (default false)See the OpenAPI schema for allowed values.
group_byqueryNostring (one of market, bookmaker; default market)How prices are grouped. market (the default) lists each market and outcome once, with every bookmaker's price under the outcome in prices, best price first. bookmaker lists each bookmaker with its own copy of the markets, the shape v1 launched with.
non_participantqueryNostringComma-separated non-participation rules (void, loses, under, fair_price). Keeps only player-market prices whose bookmaker settles a player who takes no part by one of these rules; prices on every other market are unaffected. For example non_participant=void keeps only player prices that are refunded when the player does not play.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/odds?league=rlwc&markets=winner&bookmakers=sportsbet&limit=1&starts_after=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch(`https://api.sockodds.com/v1/odds?league=rlwc&markets=winner&bookmakers=sportsbet&limit=1&starts_after=${new Date().toISOString().slice(0, 19)}Z`, {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request
from datetime import datetime, timezone

request = urllib.request.Request(
    f"https://api.sockodds.com/v1/odds?league=rlwc&markets=winner&bookmakers=sportsbet&limit=1&starts_after={datetime.now(timezone.utc):%Y-%m-%dT%H:%M:%SZ}",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "id": "ev_000ckk0zrx33",
      "name": "Australia v New Zealand",
      "league": {
        "key": "rlwc",
        "name": "Rugby League World Cup"
      },
      "scheduled_start": "2026-10-15T09:05:00.000Z",
      "status": "scheduled",
      "participants": [
        {
          "role": "away",
          "identity": {
            "key": "new_zealand_rugby_league",
            "name": "New Zealand"
          }
        },
        {
          "role": "home",
          "identity": {
            "key": "australia_rugby_league",
            "name": "Australia"
          }
        }
      ],
      "markets": [
        {
          "id": "mk_pz0msgze2rqwwktb",
          "key": "winner",
          "name": "Winner",
          "period": "full",
          "subject": null,
          "alternate": false,
          "outcomes": [
            {
              "id": "oc_nncgcssmzjhyt5pe",
              "name": "Australia",
              "side": "home",
              "line": null,
              "prices": [
                {
                  "bookmaker": "sportsbet",
                  "decimal_odds": 1.72,
                  "implied_probability": 0.581395,
                  "available": true,
                  "observed_at": "2026-10-15T07:58:00.000Z"
                }
              ]
            },
            {
              "id": "oc_cwsr1gda0qcgf03j",
              "name": "New Zealand",
              "side": "away",
              "line": null,
              "prices": [
                {
                  "bookmaker": "sportsbet",
                  "decimal_odds": 2.12,
                  "implied_probability": 0.471698,
                  "available": true,
                  "observed_at": "2026-10-15T07:58:00.000Z"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

WebSocket/stream/odds

Operation streamOdds · Prices

Pro and Internal only. Upgrade to a WebSocket with your bearer key to receive the current prices for one event, or for up to 20 events in one league, every 15 seconds. Each message is a JSON object whose type is snapshot (the same body as the matching odds route, grouped by market unless group_by=bookmaker), heartbeat (nothing changed) or error (a problem object, after which the connection closes). A refresh counts towards your allowance like an ordinary odds request only when it sends a new snapshot; a heartbeat (nothing changed) is free. Every refresh still counts towards your per minute request limit. Up to two streams per key. A stream lasts at most one hour; reconnect for a fresh one. The stream is read only; a message from the client closes it. Close codes are 1000 (lifetime reached), 1008 (key, plan or limit change), 1009 (snapshot too large, narrow the filters), 1011 (refresh failed) and 1013 (client reading too slowly).

ParameterInRequiredTypeMeaning
event_idqueryNoEventId (string)One event. Use this or league, not both.
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
marketsqueryNostringComma-separated market keys, at most 20.
regionsqueryNostringComma-separated bookmaker regions, at most 20.
bookmakersqueryNostringComma-separated bookmaker keys, at most 20.
alternatesqueryNoboolean (default false)See the OpenAPI schema for allowed values.
group_byqueryNostring (one of market, bookmaker; default market)How prices are grouped. market (the default) lists each market and outcome once, with every bookmaker's price under the outcome in prices, best price first. bookmaker lists each bookmaker with its own copy of the markets, the shape v1 launched with.
non_participantqueryNostringComma-separated non-participation rules (void, loses, under, fair_price). Keeps only player-market prices whose bookmaker settles a player who takes no part by one of these rules; prices on every other market are unaffected. For example non_participant=void keeps only player prices that are refunded when the player does not play.
limitqueryNointeger (minimum 1; maximum 20; default 10)With league only. Events per snapshot, 1 to 20. Defaults to 10.

Stream limits

LimitValue
Refresh interval15 seconds
Longest connection3,600 seconds
Largest snapshot8,000,000 bytes
Largest unread backlog1,000,000 bytes
Open streams per key2 streams
Events per league snapshot20 events

Close codes

CodeMeaning
1000lifetime reached
1008key, plan or limit change
1009snapshot too large, narrow the filters
1011refresh failed
1013client reading too slowly
const socket = new WebSocket("wss://api.sockodds.com/v1/stream/odds?event_id=ev_000ckk0zrx33", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
socket.addEventListener("message", (message) => {
  const frame = JSON.parse(message.data);
  if (frame.type === "heartbeat") return; // nothing changed since the last snapshot
  if (frame.type === "error") throw new Error(frame.problem.detail);
  // A snapshot is the odds route's body: one event for event_id, a list for league.
  // Prices are grouped by market, best first, so prices[0] is each outcome's best price.
  const events = Array.isArray(frame.data) ? frame.data : [frame.data];
  for (const event of events) {
    const market = event.markets[0];
    if (!market) continue;
    const best = market.outcomes.map((o) => `${o.name} ${o.prices[0].decimal_odds} (${o.prices[0].bookmaker})`);
    console.log(`${event.name}, ${market.name}: ${best.join(", ")}`);
  }
  socket.close();
});

Output from a local copy of the API with invented test prices

Australia v New Zealand, Winner: Australia 1.81 (playup), New Zealand 2.23 (playup)

GET/odds/history

Operation listOddsHistory · Prices

Pro and Internal only. Own observations recorded under the new identities only. No observation predates 22 December 2025 UTC. Changes older than the live store keeps are read from the daily history archive and returned in the same shape and order, so a window reads the same whichever store holds it. Changes are ordered by observation time, then by when they were recorded. A window may not exceed 24 hours. While older history is busy the API answers 503 with a short Retry-After.

ParameterInRequiredTypeMeaning
event_idqueryYesEventId (string)See the OpenAPI schema for allowed values.
fromqueryYesstring (date-time)See the OpenAPI schema for allowed values.
toqueryYesstring (date-time)See the OpenAPI schema for allowed values.
marketsqueryNostringComma-separated market keys, at most 20.
bookmakersqueryNostringComma-separated bookmaker keys, at most 20.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 1000; default 250)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/odds/history?event_id=ev_000ckk0zrx33&from=2026-10-15T00:00:00Z&to=2026-10-15T08:00:00Z&bookmakers=sportsbet&limit=4" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/odds/history?event_id=ev_000ckk0zrx33&from=2026-10-15T00:00:00Z&to=2026-10-15T08:00:00Z&bookmakers=sportsbet&limit=4", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/odds/history?event_id=ev_000ckk0zrx33&from=2026-10-15T00:00:00Z&to=2026-10-15T08:00:00Z&bookmakers=sportsbet&limit=4",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "event": "ev_000ckk0zrx33",
      "market": {
        "id": "mk_pz0msgze2rqwwktb",
        "key": "winner",
        "name": "Winner",
        "period": "full",
        "subject": null
      },
      "outcome": {
        "id": "oc_nncgcssmzjhyt5pe",
        "name": "Australia",
        "side": "home"
      },
      "bookmaker": "sportsbet",
      "observed_at": "2026-10-15T01:58:00.000Z",
      "kind": "opened",
      "decimal_odds": 1.79,
      "implied_probability": 0.558659,
      "line": null
    },
    {
      "event": "ev_000ckk0zrx33",
      "market": {
        "id": "mk_pz0msgze2rqwwktb",
        "key": "winner",
        "name": "Winner",
        "period": "full",
        "subject": null
      },
      "outcome": {
        "id": "oc_cwsr1gda0qcgf03j",
        "name": "New Zealand",
        "side": "away"
      },
      "bookmaker": "sportsbet",
      "observed_at": "2026-10-15T01:58:00.000Z",
      "kind": "opened",
      "decimal_odds": 2.2,
      "implied_probability": 0.454545,
      "line": null
    },
    {
      "event": "ev_000ckk0zrx33",
      "market": {
        "id": "mk_5j02m4w6004weeze",
        "key": "handicap",
        "name": "Handicap",
        "period": "full",
        "subject": null
      },
      "outcome": {
        "id": "oc_j6paqe6cbz2fy0f8",
        "name": "Australia",
        "side": "home"
      },
      "bookmaker": "sportsbet",
      "observed_at": "2026-10-15T01:58:00.000Z",
      "kind": "opened",
      "decimal_odds": 1.98,
      "implied_probability": 0.505051,
      "line": -6.5
    },
    {
      "event": "ev_000ckk0zrx33",
      "market": {
        "id": "mk_5j02m4w6004weeze",
        "key": "handicap",
        "name": "Handicap",
        "period": "full",
        "subject": null
      },
      "outcome": {
        "id": "oc_74ypb0kmrb0cbefw",
        "name": "New Zealand",
        "side": "away"
      },
      "bookmaker": "sportsbet",
      "observed_at": "2026-10-15T01:58:00.000Z",
      "kind": "opened",
      "decimal_odds": 1.98,
      "implied_probability": 0.505051,
      "line": 6.5
    }
  ],
  "meta": {
    "count": 4,
    "cursor": "eyJhdCI6IjIwMjYtMTAtMTVUMDE6NTg6MDAuMDAwWiIsImlkIjoiNTAzIiwicmV2aXNpb24iOiIxMDA1IiwiZiI6IjJkMTc0OGRkZDY4Y2UzMDEifQ"
  },
  "links": {
    "next": "https://api.sockodds.com/v1/odds/history?event_id=ev_000ckk0zrx33&from=2026-10-15T00%3A00%3A00Z&to=2026-10-15T08%3A00%3A00Z&bookmakers=sportsbet&limit=4&cursor=eyJhdCI6IjIwMjYtMTAtMTVUMDE6NTg6MDAuMDAwWiIsImlkIjoiNTAzIiwicmV2aXNpb24iOiIxMDA1IiwiZiI6IjJkMTc0OGRkZDY4Y2UzMDEifQ"
  }
}

GET/history/files

Operation listHistoryFiles · History

Pro and Internal only. Whole days of history as Parquet files, one file per league and UTC day, from 22 December 2025 up to two days ago. Each file holds the rows /v1/odds/history returns for that league and day, sorted by event and observation time. Own observations only. Listing bills one object per file listed.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/history/files?league=nfl&limit=2" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/history/files?league=nfl&limit=2", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/history/files?league=nfl&limit=2",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "league": {
        "key": "nfl",
        "name": "NFL"
      },
      "day": "2026-10-12",
      "rows": 96,
      "bytes": 3832,
      "sha256": "efea29cc589a3a93bd5bead1d7de02a09be13574441721cebdb0498c8514ecd2",
      "observed_from": "2026-10-12T00:00:00.000000Z",
      "observed_to": "2026-10-12T06:00:00.000000Z",
      "url": "https://api.sockodds.com/v1/history/files/nfl/2026-10-12"
    }
  ],
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

GET/history/files/{league}/{day}

Operation getHistoryFile · History

Pro and Internal only. Downloads one day of history as a zstd Parquet file. Columns: event_id, market_id, market_key, market_name, period, subject_key, subject_id, subject_name, outcome_id, outcome_name, side, line, bookmaker, observed_at (UTC, milliseconds), kind, decimal_odds, implied_probability. The ETag is the file's SHA-256. At most two downloads at a time per key. Each download bills one object. A file that names a player whose identity came under review after it was built answers 503 until it is rebuilt overnight.

ParameterInRequiredTypeMeaning
leaguepathYesKey (string)See the OpenAPI schema for allowed values.
daypathYesstring (date)UTC day as YYYY-MM-DD.
curl -sS -o nfl-2026-10-12.parquet -w "%{http_code} %{content_type} %{size_download}\n" "https://api.sockodds.com/v1/history/files/nfl/2026-10-12" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
import { writeFile } from "node:fs/promises";

const response = await fetch("https://api.sockodds.com/v1/history/files/nfl/2026-10-12", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
const body = Buffer.from(await response.arrayBuffer());
await writeFile("nfl-2026-10-12.parquet", body);
console.log(`${response.status} ${response.headers.get("content-type")} ${body.length}`);
import os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/history/files/nfl/2026-10-12",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    body = response.read()
    with open("nfl-2026-10-12.parquet", "wb") as out:
        out.write(body)
    print(response.status, response.headers["Content-Type"], len(body))

Output from a local copy of the API with invented test prices

200 application/vnd.apache.parquet 3832

GET/results

Operation listResults · Results

Settled outcomes for finished events, graded from official result sources. Each outcome's verdict is won, lost, void (stake returned), dead_heat, half_won or half_lost. half_won / half_lost settle an Asian quarter line (x.25 / x.75) whose two half stakes split: one half won (or lost) at the quoted price and the other half refunded. A dead heat pays dead_heat_factor of the stake at the quoted price and loses the rest: a drawn AFL or AFLW head-to-head, a drawn AFLW quarter or half winner, a tied NBL quarter or half winner, and a Rugby League World Cup head-to-head still level after golden point, is a dead heat with a factor of 0.5. Outcomes that official evidence cannot settle are left out, never guessed. Each market settles on its own once official evidence settles all of its outcomes, so a result can be published while other markets on the event are still pending: settlement is partial and pending_markets counts them, and later results for the same event add the newly settled outcomes without changing any verdict already published.

ParameterInRequiredTypeMeaning
leaguequeryNoKey (string)See the OpenAPI schema for allowed values.
event_idqueryNoEventId (string)Restrict results to one independent event identity.
starts_afterqueryNostring (date-time)See the OpenAPI schema for allowed values.
starts_beforequeryNostring (date-time)See the OpenAPI schema for allowed values.
cursorqueryNostringSee the OpenAPI schema for allowed values.
limitqueryNointeger (minimum 1; maximum 100; default 25)See the OpenAPI schema for allowed values.
curl -sS "https://api.sockodds.com/v1/results?league=nfl&limit=1" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/results?league=nfl&limit=1", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/results?league=nfl&limit=1",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": [
    {
      "event": {
        "id": "ev_000ckk0h3n6r",
        "name": "Arizona Cardinals v Atlanta Falcons",
        "league": {
          "key": "nfl",
          "name": "NFL"
        },
        "scheduled_start": "2026-10-12T08:00:00.000Z",
        "status": "final",
        "participants": [
          {
            "role": "away",
            "identity": {
              "key": "atlanta_falcons",
              "name": "Atlanta Falcons"
            }
          },
          {
            "role": "home",
            "identity": {
              "key": "arizona_cardinals",
              "name": "Arizona Cardinals"
            }
          }
        ]
      },
      "status": "final",
      "settlement": "partial",
      "pending_markets": 1,
      "settled_at": "2026-10-12T12:00:00.000Z",
      "outcomes": [
        {
          "id": "oc_1xh21t2rzp7ss665",
          "name": "Atlanta Falcons",
          "verdict": "lost",
          "market": {
            "id": "mk_s4fv79z47rbkwev7",
            "key": "winner",
            "name": "Winner",
            "period": "full",
            "subject": null
          },
          "side": "away",
          "line": null
        },
        {
          "id": "oc_53f4yzaqeyex1xhg",
          "name": "Arizona Cardinals",
          "verdict": "won",
          "market": {
            "id": "mk_s4fv79z47rbkwev7",
            "key": "winner",
            "name": "Winner",
            "period": "full",
            "subject": null
          },
          "side": "home",
          "line": null
        },
        {
          "id": "oc_7txwsxyatthp1bqb",
          "name": "Arizona Cardinals",
          "verdict": "won",
          "market": {
            "id": "mk_5tz5q3wkht6h0pme",
            "key": "handicap",
            "name": "Handicap",
            "period": "full",
            "subject": null
          },
          "side": "home",
          "line": -3.5
        },
        {
          "id": "oc_yxchy92ev1h1abxs",
          "name": "Atlanta Falcons",
          "verdict": "lost",
          "market": {
            "id": "mk_5tz5q3wkht6h0pme",
            "key": "handicap",
            "name": "Handicap",
            "period": "full",
            "subject": null
          },
          "side": "away",
          "line": 3.5
        }
      ]
    }
  ],
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

Objects

Every object the API returns, generated from the contract. Required fields are always present; a field typed with null may be null.

Meta

FieldRequiredTypeMeaning
countYesinteger (minimum 0)
cursorYesstring or null

NamedKey

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring

League

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
sportNoKey (string)
regionNoKey (string)

Bookmaker

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
regionsNoarray of Key (string)
kindNostring (one of sportsbook, exchange, prediction_market)

Sport

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
participantsYesstring (one of teams, competitors)Who contests an event. Team sports use the participant roles home and away; individual sports (tennis

MarketDescriptor

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
subjectNostring (one of event, team, player)
periodsNoarray of Key (string)
ungraded_periodsNoarray of Key (string)Periods this market is quoted for but not yet graded, because no results source supplies the statistic yet. Results for quotes in these periods stay pending. Listed where audited; its absence is not a guarantee that a period grades. It is per market across all its sports, so a period is listed if it is ungraded in any of them.
sportsNoarray of Key (string)
non_participantNoarray of NonParticipant (one of void, loses, under, fair_price)Player markets only. The non-participation rules a price on this market may carry (see the non_participant of each price in the odds routes). Every player-market price carries one.
sidesNoarray of Key (string) or string (one of participants, scores)Side keys, or participants when each outcome is a player runner, or scores for exact-score outcomes. A market offers home and away only in team sports and competitor_1 and competitor_2 only in tennis and UFC.

Team

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
sportYesKey (string)
leaguesNoarray of Key (string)

Player

FieldRequiredTypeMeaning
idYesPlayerId (string)
nameYesstring
sportYesKey (string)
teamYesNamedKey or null

Participant

FieldRequiredTypeMeaning
roleYesstring (one of home, away, competitor_1, competitor_2)home and away in team sports. In tennis and UFC
identityYesNamedKey or object

Event

FieldRequiredTypeMeaning
idYesEventId (string)
nameYesstring
leagueYesNamedKey
scheduled_startYesstring (date-time)
cricket_formatNostring (one of odi, test)Official format
statusYesstring (one of scheduled, live, final, postponed, cancelled)
participantsYesarray of Participant

EventLookup

FieldRequiredTypeMeaning
sourceYesOfficialSource (one of espn, afl, nrl)
refYesOfficialRef (string)
eventYesEvent

ExchangeContract

Native buy contract underlying the enclosing rounded decimal odds. Available is a native quantity; price is the fraction of payout per share/contract. Buy cost equals price times available times payout_per_contract before fees; omitted payout means 1. Novig pays USD 0.01 per contract, Fanatics Markets USD 1. An opposite contract is not a lay.

FieldRequiredTypeMeaning
selection_refYesstring
sideYesstring
unitYesstring (one of contracts, shares)
priceYesnumber (greater than 0; less than 1)
availableNonumber (minimum 0)
payout_per_contractNonumber (one of 0.01, 1)Native monetary payout in liquidity.currency per contract; omitted means 1 for existing feeds.

ExchangeLiquidity

Verified native exchange depth for this outcome, line and quoted back price, at the enclosing price's observed_at. Available amounts are resting stake, not guaranteed account limits or lay liability. Absent when not reported or the current price is unavailable.

FieldRequiredTypeMeaning
market_refNostringNative exchange market reference; joins the market-level exchanges entry.
offer_refNostringBetOpenly offer identifier when the feed supplies no native market ID.
contractNoExchangeContract
currencyYesstring or null (pattern ^[A-Z]{3}$)Capture currency when verified; null means unknown. Never infer currency from bookmaker region.
available_to_backNonumber (minimum 0)Unrounded amount available at the enclosing decimal_odds.
layNoobject
lay.decimal_oddsYesnumber (greater than 1)Best lay price for this same selection and line.
lay.availableNonumber (minimum 0)Resting stake available at this lay price

ExchangeMarket

One native exchange market's reported activity. Missing matched_volume means unreported, never zero. Kalshi and Novig traded_contracts is a count, not money. Never sum runner volumes. A native market can span canonical lines; the same market_ref total may therefore appear under multiple lines and must not be added together. Current observations only; no liquidity history or opening/closing volume is promised.

FieldRequiredTypeMeaning
bookmakerYesKey (string)
market_refYesstring
matched_volumeNonumber (minimum 0)Verified monetary volume from the native market
traded_contractsNonumber (minimum 0)Kalshi volume_fp or Novig native market volume in contracts. This is not matched money.
currencyYesstring or null (pattern ^[A-Z]{3}$)
observed_atYesstring (date-time)

Outcome

FieldRequiredTypeMeaning
liquidityNoExchangeLiquidity
idYesOutcomeId (string)
nameYesstring
sideYesstringA catalogue side key or player runner ID. Team sports name participants home and away; tennis and UFC name them competitor_1 and competitor_2
lineYesnumber or nullThe outcome's own line. On a handicap each outcome carries its own figure: home -6.5 with away +6.5, and in tennis competitor_1 -2.5 with competitor_2 +2.5 (games). Null when the market has no line.
decimal_oddsYesnumber or null (greater than 1)
implied_probabilityYesnumber or null (greater than 0; maximum 1)
availableNobooleanWhether the current quote is available and fresh. Stale or withdrawn quotes appear only when snapshots are requested and carry null current prices.
alternateYesboolean
non_participantNoNonParticipant (one of void, loses, under, fair_price)Player markets only, and only when the rule is not void: this shape stays byte for byte the launch body, so an absent value on a player market means void. Grouped by market, every player price carries it.
bookmakerYesKey (string)
observed_atYesstring (date-time)
openingNoPriceSnapshot or nullThe first quote before the snapshots cutoff, skipping withdrawals. Null when there is none.
closingNoPriceSnapshot or nullThe last quote before the snapshots cutoff. Null when there is none. For every sport but MMA it is also null when that last row is a withdrawal (the book pulled the price before scheduled_start); it never falls back to an earlier price. For an MMA bout withdrawals are skipped, so closing is the last price offered before the cutoff.

PriceSnapshot

FieldRequiredTypeMeaning
decimal_oddsYesnumber (greater than 1)
implied_probabilityYesnumber (greater than 0; maximum 1)
observed_atYesstring (date-time)

QuotedMarket

FieldRequiredTypeMeaning
exchangesNoarray of ExchangeMarket
idYesMarketId (string)
keyYesKey (string)
nameYesstring
subjectYesnull or NamedKey or object
periodYesKey (string)
outcomesYesarray of Outcome

Price

One bookmaker's current price for an outcome.

FieldRequiredTypeMeaning
liquidityNoExchangeLiquidity
bookmakerYesKey (string)
decimal_oddsYesnumber or null (greater than 1)
implied_probabilityYesnumber or null (greater than 0; maximum 1)
availableYesbooleanWhether the quote is available and fresh. Stale or withdrawn quotes appear only when snapshots are requested and carry null current prices.
openingNoPriceSnapshot or nullThe first quote before the snapshots cutoff, skipping withdrawals. Null when there is none.
closingNoPriceSnapshot or nullThe last quote before the snapshots cutoff. Null when there is none. For every sport but MMA it is also null when that last row is a withdrawal (the book pulled the price before scheduled_start); it never falls back to an earlier price. For an MMA bout withdrawals are skipped, so closing is the last price offered before the cutoff.
non_participantNoNonParticipant (one of void, loses, under, fair_price)
observed_atYesstring (date-time)

PricedOutcome

FieldRequiredTypeMeaning
idYesOutcomeId (string)
nameYesstring
sideYesstringA catalogue side key or player runner ID
lineYesnumber or nullThe outcome's own line: home -6.5 with away +6.5. Null when the market has no line.
pricesYesarray of PriceEvery bookmaker price for this outcome, best first: highest decimal odds, then bookmaker key. prices[0] is the best price among the bookmakers asked for. A price with no current odds (snapshots only) comes last.

PricedMarket

FieldRequiredTypeMeaning
exchangesNoarray of ExchangeMarket
idYesMarketId (string)
keyYesKey (string)
nameYesstring
periodYesKey (string)
subjectYesnull or NamedKey or object
alternateYesbooleanTrue when this line is not the market's main line. Alternate lines appear only with alternates=true.
outcomesYesarray of PricedOutcomeIn the market's side order (home

QuotedBookmaker

FieldRequiredTypeMeaning
keyYesKey (string)
nameYesstring
marketsYesarray of QuotedMarket

OddsEvent

An event with its prices grouped by market (the default). Markets come in catalogue order, then period, subject and line.

FieldRequiredTypeMeaning
idYesEventId (string)
nameYesstring
leagueYesNamedKey
scheduled_startYesstring (date-time)
cricket_formatNostring (one of odi, test)Official format
statusYesstring (one of scheduled, live, final, postponed, cancelled)
participantsYesarray of Participant
marketsYesarray of PricedMarket

OddsEventByBookmaker

An event with its prices grouped by bookmaker (group_by=bookmaker), the shape v1 launched with.

FieldRequiredTypeMeaning
idYesEventId (string)
nameYesstring
leagueYesNamedKey
scheduled_startYesstring (date-time)
cricket_formatNostring (one of odi, test)Official format
statusYesstring (one of scheduled, live, final, postponed, cancelled)
participantsYesarray of Participant
bookmakersYesarray of QuotedBookmaker

RecordedMarket

FieldRequiredTypeMeaning
idYesMarketId (string)
keyYesKey (string)
nameYesstring
periodYesKey (string)
subjectYesNamedKey or object or null

HistoryChange

FieldRequiredTypeMeaning
eventYesEventId (string)
marketYesRecordedMarket
outcomeYesobject
outcome.idYesOutcomeId (string)
outcome.nameYesstring
outcome.sideYesstring
bookmakerYesKey (string)
observed_atYesstring (date-time)
kindYesstring (one of opened, changed, withdrawn)
decimal_oddsYesnumber or null
implied_probabilityNonumber or null
lineNonumber or null

HistoryFile

FieldRequiredTypeMeaning
leagueYesNamedKey
dayYesstring (date)
rowsYesinteger (minimum 1)
bytesYesinteger (minimum 1)
sha256Yesstring (pattern ^[0-9a-f]{64}$)
observed_fromYesstring (date-time)
observed_toYesstring (date-time)
urlYesstring (uri)

Result

FieldRequiredTypeMeaning
eventYesEvent
statusYesstring (one of final, corrected)
settlementYesstring (one of complete, partial)complete when every quoted market on the event is settled; partial while any market is still pending.
pending_marketsYesinteger (minimum 0)How many quoted markets on the event are still pending. A market is pending until official evidence settles every one of its outcomes.
settled_atYesstring (date-time)
outcomesYesarray of object
outcomes[].idYesOutcomeId (string)
outcomes[].nameYesstring
outcomes[].verdictYesstring (one of won, lost, void, dead_heat, half_won, half_lost)half_won / half_lost: an Asian quarter line (x.25 / x.75) whose two half stakes split: one half won (or lost) at the quoted price and the other half refunded.
outcomes[].dead_heat_factorWhen verdict is dead_heatnumber (greater than 0; less than 1)Dead heats only: the share of the stake paid at the quoted price. The rest of the stake is lost.
outcomes[].marketYesRecordedMarket
outcomes[].sideYesstring
outcomes[].lineYesnumber or null

Problem

FieldRequiredTypeMeaning
typeYesstring (uri-reference)
titleYesstring
statusYesinteger
detailYesstring
instanceYesstring (uri-reference)

Identifier formats

NameFormat
Keystring (pattern ^[a-z][a-z0-9_]{1,47}$)
EventIdstring (pattern ^ev_[0-9a-hjkmnp-tv-z]{12}$)
PlayerIdstring (pattern ^pl_[0-9a-hjkmnp-tv-z]{12}$)
MarketIdstring (pattern ^mk_[0-9a-hjkmnp-tv-z]{16}$)
OutcomeIdstring (pattern ^oc_[0-9a-hjkmnp-tv-z]{16}$)
OfficialSourcestring (one of espn, afl, nrl)
OfficialRefstring (pattern ^[A-Za-z0-9][A-Za-z0-9:~._-]{0,63}$)
NonParticipantstring (one of void, loses, under, fair_price)
Need help?FAQ · Email support

Search across the SockOdds documentation and catalogue.