> ## Documentation Index
> Fetch the complete documentation index at: https://docs.therundown.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Player Props

> Fetch player prop odds including points, rebounds, assists, three-pointers, and combo markets using the V2 markets system.

Player prop markets let you get odds on individual player performance -- points scored, rebounds, assists, and more. TheRundown V2 API models player props as markets with `type` of `TYPE_PLAYER`.

## Player Prop Market IDs

### Individual Stats

| Market              | ID | Description                         |
| ------------------- | -- | ----------------------------------- |
| Player Points       | 29 | Over/Under on points scored         |
| Player Turnovers    | 33 | Over/Under on turnovers             |
| Player Rebounds     | 35 | Over/Under on rebounds              |
| Three Pointers Made | 38 | Over/Under on 3PT made              |
| Player Assists      | 39 | Over/Under on assists               |
| Double Double       | 87 | Yes/No on recording a double-double |
| Triple Double       | 88 | Yes/No on recording a triple-double |
| Player Blocks       | 98 | Over/Under on blocks                |

### Combo Markets

Combo markets combine two or three stats into a single over/under line.

| Market                    | ID  | Description                          |
| ------------------------- | --- | ------------------------------------ |
| Player PRA                | 93  | Points + Rebounds + Assists combined |
| Player Points + Assists   | 99  | Points + Assists combined            |
| Player Points + Rebounds  | 297 | Points + Rebounds combined           |
| Player Rebounds + Assists | 298 | Rebounds + Assists combined          |

### Live / In-Play Variants

Live player props use separate market IDs but map to their prematch equivalents.

| Market                         | ID  | Prematch Equivalent |
| ------------------------------ | --- | ------------------- |
| Live Player Points             | 90  | 29                  |
| Live Player Assists            | 91  | 39                  |
| Live Three Pointers            | 92  | 38                  |
| Live Player Rebounds           | 982 | 35                  |
| Live Player Blocks             | 983 | 98                  |
| Live Player Turnovers          | 984 | 33                  |
| Live Double Double             | 985 | 87                  |
| Live Triple Double             | 986 | 88                  |
| Live Player PRA                | 987 | 93                  |
| Live Player Points + Rebounds  | 988 | 297                 |
| Live Player Points + Assists   | 989 | 99                  |
| Live Player Rebounds + Assists | 990 | 298                 |

## Discovering Available Prop Markets

The tables above are a reference, but not every sport or event will have every prop market. Use the market discovery endpoints to see which prop markets are currently available.

### By sport and date

Returns all markets with active pricing for a sport on a given date. Filter to player props by checking the `proposition` field — prop markets have `proposition: true`.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://therundown.io/api/v2/sports/4/markets/2026-02-12?key=YOUR_API_KEY&offset=300"
  ```

  ```python Python theme={null}
  import requests
  from datetime import date

  API_KEY = "YOUR_API_KEY"
  BASE_URL = "https://therundown.io/api/v2"

  response = requests.get(
      f"{BASE_URL}/sports/4/markets/{date.today()}",
      params={"key": API_KEY, "offset": "300"}
  )

  # Response is keyed by sport ID
  for market in response.json().get("4", []):
      if market.get("proposition"):
          print(f"  {market['id']:>4}  {market['name']}")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "YOUR_API_KEY";
  const BASE_URL = "https://therundown.io/api/v2";
  const today = new Date().toISOString().split("T")[0];

  const response = await fetch(
    `${BASE_URL}/sports/4/markets/${today}?key=${API_KEY}&offset=300`
  );
  const marketsBySport = await response.json();

  for (const market of marketsBySport["4"] || []) {
    if (market.proposition) {
      console.log(`  ${market.id}  ${market.name}`);
    }
  }
  ```
</CodeGroup>

### By event ID

Returns only the markets available for a specific event. Useful when building a props view for a single game.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://therundown.io/api/v2/events/EVENT_ID/markets?key=YOUR_API_KEY"
  ```

  ```python Python theme={null}
  event_id = "EVENT_ID"
  response = requests.get(
      f"{BASE_URL}/events/{event_id}/markets",
      params={"key": API_KEY}
  )

  for market in response.json():
      if market.get("proposition"):
          print(f"  {market['id']:>4}  {market['name']}")
  ```

  ```javascript JavaScript theme={null}
  const eventId = "EVENT_ID";
  const response = await fetch(
    `${BASE_URL}/events/${eventId}/markets?key=${API_KEY}`
  );
  const markets = await response.json();

  for (const market of markets) {
    if (market.proposition) {
      console.log(`  ${market.id}  ${market.name}`);
    }
  }
  ```
</CodeGroup>

Pass the V2 `event_id` from the event payload into per-event endpoints. Do not substitute `event_uuid`.

Use the discovered market IDs in the `market_ids` parameter when fetching events to get odds for those props.

***

## Fetching Player Props

Request player prop markets by including the relevant `market_ids` in your events request.

<CodeGroup>
  ```bash cURL theme={null}
  # NBA player points, rebounds, assists, and 3PT props
  curl "https://therundown.io/api/v2/sports/4/events/2026-02-12?\
  key=YOUR_API_KEY&market_ids=29,35,38,39&affiliate_ids=19,23&offset=300"
  ```

  ```python Python theme={null}
  import requests
  from datetime import date

  API_KEY = "YOUR_API_KEY"
  BASE_URL = "https://therundown.io/api/v2"

  # Fetch individual stat props
  PROP_MARKETS = "29,35,38,39"  # Points, Rebounds, 3PT, Assists

  response = requests.get(
      f"{BASE_URL}/sports/4/events/{date.today()}",
      params={
          "key": API_KEY,
          "market_ids": PROP_MARKETS,
          "affiliate_ids": "19,23",
          "offset": "300",
      }
  )

  data = response.json()
  for event in data["events"]:
      home = event["teams"][1]["name"]
      away = event["teams"][0]["name"]
      print(f"\n{'=' * 60}")
      print(f"{away} @ {home}")

      for market in event.get("markets", []):
          print(f"\n  {market['name']} (ID: {market['market_id']})")
          for participant in market["participants"]:
              for line in participant["lines"]:
                  for aff_id, price in line["prices"].items():
                      over_under = "O" if "Over" in participant.get("name", "") or \
                          participant.get("type") == "TYPE_OVER" else "U"
                      print(
                          f"    {participant['name']}: "
                          f"{over_under} {line.get('value', 'N/A')} "
                          f"({price['price']}) @ {aff_id}"
                      )
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "YOUR_API_KEY";
  const BASE_URL = "https://therundown.io/api/v2";
  const today = new Date().toISOString().split("T")[0];

  // Fetch individual stat props
  const PROP_MARKETS = "29,35,38,39"; // Points, Rebounds, 3PT, Assists

  const params = new URLSearchParams({
    key: API_KEY,
    market_ids: PROP_MARKETS,
    affiliate_ids: "19,23",
    offset: "300",
  });

  const response = await fetch(
    `${BASE_URL}/sports/4/events/${today}?${params}`
  );
  const data = await response.json();

  for (const event of data.events) {
    const away = event.teams[0].name;
    const home = event.teams[1].name;
    console.log(`\n${"=".repeat(60)}`);
    console.log(`${away} @ ${home}`);

    for (const market of event.markets || []) {
      console.log(`\n  ${market.name} (ID: ${market.market_id})`);
      for (const participant of market.participants) {
        for (const line of participant.lines) {
          for (const [affId, price] of Object.entries(line.prices)) {
            const overUnder =
              participant.name.includes("Over") ||
              participant.type === "TYPE_OVER"
                ? "O"
                : "U";
            console.log(
              `    ${participant.name}: ${overUnder} ${line.value ?? "N/A"} (${price.price}) @ ${affId}`
            );
          }
        }
      }
    }
  }
  ```
</CodeGroup>

## Understanding Participants in Player Props

In player prop markets, participants represent the player (not the team). Each participant has:

| Field  | Description                              |
| ------ | ---------------------------------------- |
| `id`   | Unique numeric identifier for the player |
| `name` | Player name (e.g., "LeBron James")       |
| `type` | `TYPE_PLAYER` for player props           |

Within each participant, the `lines` array contains the over/under values and their prices from each sportsbook. Each line has a `value` field (a string, e.g., `"25.5"`) and a `prices` map keyed by affiliate ID. Each price object includes the `price`, `is_main_line` boolean, and `updated_at` timestamp.

<Note>
  **Join player props on `participant.id`, not `name`.** For `TYPE_PLAYER` participants, `id` is the stable player ID — the same key used everywhere else in the API. Fetch the full player record (team, names, position) at `GET /api/v2/players/{player_id}`. Because each player has a distinct `id`, joining on `id` resolves shared-name collisions that joining on `name` cannot. To resolve a name to an `id` once, use the roster at `GET /api/v2/teams/{team_id}/players`. You can also narrow the response server-side with `participant_ids` (comma-separated, max 99) and `participant_type=TYPE_PLAYER`. See the [Participant object](/reference/data-model#participant-object) reference for full definitions.
</Note>

### Example Response Structure

```json theme={null}
{
  "market_id": 29,
  "name": "Player Points",
  "period_id": 0,
  "participants": [
    {
      "id": 12345,
      "name": "LeBron James Over",
      "type": "TYPE_OVER",
      "lines": [
        {
          "value": "25.5",
          "prices": {
            "19": { "price": -115, "is_main_line": true, "updated_at": "2026-02-12T18:30:00Z" },
            "23": { "price": -110, "is_main_line": true, "updated_at": "2026-02-12T18:29:45Z" }
          }
        }
      ]
    },
    {
      "id": 12345,
      "name": "LeBron James Under",
      "type": "TYPE_UNDER",
      "lines": [
        {
          "value": "25.5",
          "prices": {
            "19": { "price": -105, "is_main_line": true, "updated_at": "2026-02-12T18:30:00Z" },
            "23": { "price": -110, "is_main_line": true, "updated_at": "2026-02-12T18:29:45Z" }
          }
        }
      ]
    }
  ]
}
```

## Fetching Combo Props

Combo markets combine multiple stats. The request pattern is the same -- just use the combo market IDs.

<CodeGroup>
  ```python Python theme={null}
  # Fetch combo props: PRA, PA, PR, RA
  COMBO_MARKETS = "93,99,297,298"

  response = requests.get(
      f"{BASE_URL}/sports/4/events/{date.today()}",
      params={
          "key": API_KEY,
          "market_ids": COMBO_MARKETS,
          "affiliate_ids": "19",
      }
  )

  data = response.json()
  for event in data["events"]:
      print(f"\n{event['teams'][0]['name']} @ {event['teams'][1]['name']}")
      for market in event.get("markets", []):
          print(f"\n  {market['name']}:")
          for participant in market["participants"]:
              for line in participant["lines"]:
                  price_obj = line["prices"].get("19", {})
                  price = price_obj.get("price", "N/A")
                  print(f"    {participant['name']}: {line.get('value')} ({price})")
  ```

  ```javascript JavaScript theme={null}
  // Fetch combo props: PRA, PA, PR, RA
  const COMBO_MARKETS = "93,99,297,298";

  const params = new URLSearchParams({
    key: API_KEY,
    market_ids: COMBO_MARKETS,
    affiliate_ids: "19",
  });

  const response = await fetch(
    `${BASE_URL}/sports/4/events/${today}?${params}`
  );
  const data = await response.json();

  for (const event of data.events) {
    console.log(`\n${event.teams[0].name} @ ${event.teams[1].name}`);
    for (const market of event.markets || []) {
      console.log(`\n  ${market.name}:`);
      for (const participant of market.participants) {
        for (const line of participant.lines) {
          const price = line.prices["19"]?.price ?? "N/A";
          console.log(`    ${participant.name}: ${line.value} (${price})`);
        }
      }
    }
  }
  ```
</CodeGroup>

## Fetching All Props at Once

You can request all prop market IDs in a single call. This is useful if you want to build a comprehensive player props page.

```bash theme={null}
# All individual + combo props
curl "https://therundown.io/api/v2/sports/4/events/2026-02-12?\
key=YOUR_API_KEY\
&market_ids=29,33,35,38,39,87,88,93,98,99,297,298\
&affiliate_ids=19,23"
```

## Live Player Props

Live player props are available once a game starts. Use the live market IDs to fetch in-play prop odds.

```bash theme={null}
# Live player points (90), assists (91), 3PT (92)
curl "https://therundown.io/api/v2/sports/4/events/2026-02-12?\
key=YOUR_API_KEY&market_ids=90,91,92&affiliate_ids=19"
```

You can also subscribe to live prop updates via the V2 Markets WebSocket:

```javascript theme={null}
const ws = new WebSocket(
  "wss://therundown.io/api/v2/ws/markets?key=YOUR_API_KEY&sport_ids=4&market_ids=90,91,92"
);

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.meta?.type === "heartbeat") return;

  console.log(`Live prop update: market=${data.market_id}`);
  for (const participant of data.participants || []) {
    console.log(`  ${participant.name}`);
  }
};
```

## Building a Player Props Display

Here is a complete example that organizes props by player for display in a UI.

```python theme={null}
import requests
from collections import defaultdict
from datetime import date

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://therundown.io/api/v2"

MARKET_NAMES = {
    29: "Points", 35: "Rebounds", 38: "3PT Made",
    39: "Assists", 93: "PRA", 98: "Blocks",
    99: "Pts+Ast", 297: "Pts+Reb", 298: "Reb+Ast",
}

response = requests.get(
    f"{BASE_URL}/sports/4/events/{date.today()}",
    params={
        "key": API_KEY,
        "market_ids": ",".join(str(m) for m in MARKET_NAMES),
        "affiliate_ids": "19",
        "main_line": "true",
    }
)

data = response.json()

for event in data["events"]:
    home = event["teams"][1]["name"]
    away = event["teams"][0]["name"]
    print(f"\n{'=' * 60}")
    print(f"{away} @ {home}")
    print(f"{'=' * 60}")

    # Group props by player
    players = defaultdict(list)

    for market in event.get("markets", []):
        mid = market["market_id"]
        market_label = MARKET_NAMES.get(mid, market["name"])

        for participant in market["participants"]:
            # Extract player name (remove "Over"/"Under" suffix)
            player_name = participant["name"]
            for suffix in [" Over", " Under"]:
                player_name = player_name.replace(suffix, "")

            is_over = "Over" in participant.get("name", "") or \
                participant.get("type") == "TYPE_OVER"

            for line in participant["lines"]:
                price_obj = line["prices"].get("19", {})
                price = price_obj.get("price")
                if price == 0.0001:
                    price = None

                players[player_name].append({
                    "market": market_label,
                    "value": line.get("value"),
                    "side": "Over" if is_over else "Under",
                    "price": price,
                })

    # Display grouped by player
    for player, props in sorted(players.items()):
        print(f"\n  {player}:")
        for prop in props:
            price_str = f"{prop['price']:+d}" if prop["price"] else "N/A"
            print(f"    {prop['market']}: {prop['side']} {prop['value']} ({price_str})")
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Market IDs Reference" icon="hashtag" href="/reference/markets">
    Full list of all market IDs
  </Card>

  <Card title="Getting Live Odds" icon="signal" href="/guides/getting-live-odds">
    Core game odds (moneyline, spread, total)
  </Card>

  <Card title="WebSocket Streaming" icon="bolt" href="/guides/websocket-streaming">
    Real-time updates for live props
  </Card>

  <Card title="Historical Odds" icon="chart-line" href="/guides/historical-odds">
    Track prop line movement over time
  </Card>
</CardGroup>
