Fixtures (browsing markets)
Before you can place a trade, you need a contractId. The three endpoints in this doc walk you down the fixtures hierarchy until you have one.
Auth: ISV-only JWT (see Authentication). These aren't user-scoped, so no sub or subsig needed.
1. The hierarchy
Tournament (e.g. "NBA")
└─ Sport event (e.g. "Detroit Pistons at Cleveland Cavaliers")
└─ Market (e.g. "Moneyline")
└─ Selection (= outcome) — each has a contractId
A contract is the unique combination of (event, market, outcome, strike). Its contractId is the hash you'll pass to the order endpoints. See Market Orders (single-contract trades) and Parlays.
The usual drill-down: pick a tournament, list its events, list the markets on an event, pick a selection, grab the contractId.
2. GET /private/v1/tournaments
GET /private/v1/tournaments| Query | Default | Effect |
|---|---|---|
hasActiveEvents | unset | Set to true to filter to tournaments that have at least one currently-active event. |
Response (TournamentsResponse): the response is { "tournaments": [...] }. A trimmed staging example showing the first three entries from a hasActiveEvents=true query (the full list returned ten):
{
"tournaments": [
{
"id": 31,
"name": "NFL",
"sport": { "id": 16, "name": "American Football" },
"category": { "id": 0, "name": "N/A", "countryCode": "N/A" },
"updatedAt": "2024-07-12T02:00:27.859Z"
},
{
"id": 53,
"name": "FIFA World Cup",
"sport": { "id": 1, "name": "Soccer" },
"category": { "id": 0, "name": "N/A", "countryCode": "N/A" },
"updatedAt": "2026-05-11T15:15:19.506Z"
},
{
"id": 109,
"name": "MLB",
"sport": { "id": 2, "name": "Basketball" },
"category": { "id": 0, "name": "N/A", "countryCode": "N/A" },
"updatedAt": "2024-07-12T02:00:27.296Z"
}
]
}Staging frequently returns
categoryas theN/Aplaceholder; production data is more populated. Don't rely oncategoryfor routing — usesport.nameandname.
3. GET /private/v1/sport-events
GET /private/v1/sport-events| Query | Required | Effect |
|---|---|---|
tournamentId | one of these | Filter to a single tournament. |
eventIds | one of these | Comma-separated list of event IDs. |
You typically call this after picking a tournament. The full response is { "sportEvents": [...] }. Per-event shape (SportEvent) — a real staging row for an NBA matchup from ?tournamentId=132:
{
"eventId": 20023797,
"name": "Detroit Pistons at Cleveland Cavaliers",
"displayName": "Detroit Pistons at Cleveland Cavaliers",
"liveDisabled": false,
"status": "not_started",
"type": "",
"subType": "",
"scheduled": "2026-05-15T23:00:00Z",
"updatedAt": "2026-05-14T03:29:13.952Z",
"sportName": "Basketball",
"tournamentId": 132,
"tournamentName": "NBA",
"competitors": [
{ "id": 20000012, "name": "Cleveland Cavaliers", "displayName": "Cleveland Cavaliers", "abbreviation": "CLE", "country": "", "side": "home" },
{ "id": 20000014, "name": "Detroit Pistons", "displayName": "Detroit Pistons", "abbreviation": "DET", "country": "", "side": "away" }
]
}Things to notice from real data: status is one of not_started, live, etc. (not scheduled); type and subType are often empty strings rather than null; country may be empty.
4. GET /private/v1/markets
GET /private/v1/markets| Query | Required | Effect |
|---|---|---|
eventIds | yes | Comma-separated event IDs. |
types | no | Comma-separated market types, e.g. moneyline,total. |
subTypes | no | Comma-separated market sub-types. |
Response (MarketsResponse): the response is { "markets": [{ "eventId": ..., "markets": [...] }, ...] } — one entry per event you queried, each carrying its own markets array. Below is a real moneyline market returned from a live ATP Monte Carlo singles match, showing the typical shape of a market with partial liquidity (one side has a resting price, the other side is empty):
{
"id": 186,
"name": "Moneyline",
"type": "moneyline",
"subType": "moneyline",
"status": "active",
"favorite": false,
"categoryName": "Game Lines",
"groupName": "",
"strike": 0,
"totalQuantity": 10,
"totalFilled": 0,
"playerId": 0,
"updatedAt": "2026-04-03T19:32:34.503Z",
"selections": [
[
{
"outcomeId": 4,
"contractId": "2d179d1578e669e97a2e57735f0cbef8",
"name": "Alexander Shevchenko",
"displayName": "Alexander Shevchenko",
"displayPrice": "",
"displayStrike": "",
"price": 0,
"quantity": 0,
"strike": 0,
"marketId": 0,
"competitorId": 1700000826,
"value": 0,
"updatedAt": "1970-01-01T00:00:00Z"
}
],
[
{
"outcomeId": 5,
"contractId": "05d1b7df6b4a41016d545c3944e754e0",
"name": "Andrea Pellegrino",
"displayName": "Andrea Pellegrino +100",
"displayPrice": "+100",
"displayStrike": "",
"price": 100,
"quantity": 10,
"strike": 0,
"marketId": 186,
"competitorId": 1700000749,
"value": 10,
"updatedAt": "2026-04-29T07:39:08.945Z"
}
]
]
}Fields worth knowing:
selectionsis a list of lists — each inner array holds the variants for one outcome. Most simple markets give you one entry per outcome, but you should iterate the outer list and then the inner list rather than assuming a flat array.contractIdis the thing you trade — pass it to/market-ordersor/parlays.displayPriceanddisplayStrikeare strings (e.g."+100","-110", or""when no price exists).priceis a number for the same value.priceis raw American price; the response also carries anadjustedPricefield after the ISV fee on production-priced markets. Show the adjusted one to your user where present.quantityis current liquidity at the displayed price.0means no resting orders on that side yet.strikeis the handicap/spread value (0for moneyline).- An unpriced selection shows
displayPrice: "",price: 0,quantity: 0,marketId: 0, andupdatedAt: "1970-01-01T00:00:00Z"— i.e. the contract exists but has no resting liquidity. Don't show0as-0/+0odds to your user; treat the emptydisplayPriceas "no price yet". - Pre-game events (e.g. an NBA game scheduled for tomorrow) often return the full markets catalog with every selection in this unpriced state. As the event approaches start time, sides get populated.
For markets composed of sub-markets, expect a sibling marketLines array on the parent market carrying nested Market objects with the same shape.
5. A typical drill-down
BASE="https://isv-staging-api.betprophet.co/private/v1"
# 1. Find live tournaments
curl "$BASE/tournaments?hasActiveEvents=true" -H "Authorization: Bearer $JWT_ISV"
# 2. Enumerate events in one of them — e.g. NBA (tournamentId=132)
curl "$BASE/sport-events?tournamentId=132" -H "Authorization: Bearer $JWT_ISV"
# 3. Pull the markets for an event — e.g. Detroit Pistons @ Cleveland Cavaliers
curl "$BASE/markets?eventIds=20023797&types=moneyline,total" \
-H "Authorization: Bearer $JWT_ISV"
# Pick a selections[].contractId — now you're ready to submit an order.6. Keeping data fresh
These endpoints return snapshots. To get notified when prices, liquidity, or contract status change without polling, register a webhook receiver and listen for ContractEvents — see Webhooks (push events). Use the fixtures API for discovery, and the webhook for updates.
Updated about 7 hours ago
