---
title: "Actual player ownership of one contest, one row per player and roster slot"
method: GET
path: "/api/v1/dfs/contests/{contest_id}/ownership"
tags: ["DFS"]
---

# Actual player ownership of one contest, one row per player and roster slot

`GET /api/v1/dfs/contests/{contest_id}/ownership`

## Request

- Base URL: `https://api.stat-api.com`
- URL: `https://api.stat-api.com/api/v1/dfs/contests/{contest_id}/ownership`
- Auth: HTTP bearer

The ownership that the contest's own lineups show, without the lineups. One row per player
and roster slot, from the lineup file of this contest only. The answer never reads another
contest and never falls back to the slate.

**Slots.** A classic contest has no slot: `slot` is null and the row holds the share of
lineups with the player in any seat. A single-game contest has one row per player and seat
kind: `CPT` (DraftKings captain) or `MVP` (FanDuel), and `FLEX`. The `CPT` or `MVP` rows
sum to 1.0 and the `FLEX` rows to the number of FLEX seats of the format (5 on DraftKings
Showdown), each less the share of seats for which the lineup file names no player (a
placeholder seat of the operator's file): a FLEX sum can read 4.82 to 4.98.
`position` is the natural position of the player on every row. `total_ownership`
is the player's share in any slot.

**Basis.** `actual_ownership` is `lineups / lineups_used` as a ratio from 0 to 1 with 4
decimals (0.2213 is 22.13%). `lineups_used` is the number of lineups the ownership was
computed from and `entry_count` is the entry count the operator lists, so a customer sees
whether the capture is complete. A player in no lineup has no row.

**Records.** On a plan that meters routes (Pro, Elite) one call costs 1 record for every 100
lineups of the contest (`lineups_used`), at least 5 records, whatever the number of rows it
returns and whatever the filters. A contest with 30 lineups costs 5 records, one with 190,357
lineups costs 1,904, and the largest (about 950,000 lineups) costs 9,496. An empty answer
costs 1 record, the minimum of every metered request. A caller without DFS access (no key,
a Free or Starter key) reads 5 rows and is charged for the rows it gets. A marquee contest
(GET /api/v1/dfs/marquee) is open in full: its ownership is one row per player, not per entry.

**Reading the values.** `actual_ownership` has 4 decimals. A player held by 1 of 190,357
lineups reads 0.0000 with `lineups` = 1, so use `lineups / lineups_used` or filter on
`lineups`. `position` is the operator's token: DST on DraftKings, D on FanDuel. The `slot`
filter takes CPT on DraftKings, MVP on FanDuel and FLEX on both single-game formats. A
classic contest has no slot, so `slot=FLEX` returns no row there.

**Empty answer.** The answer is 200 with no rows and a `reason`. `contest_not_final`: the
contest is not final. `in_game_format`: the contest is on an in-game format (second half,
fourth quarter, in-game Showdown), which has no ownership table. `no_lineups`: the lineup
file of the contest holds no lineup. `league_not_computed`: the actual ownership of the
contest's league is not computed (MLB, NHL, golf; NFL and NBA are). `actuals_not_recomputed`:
the ownership of the contest is not yet computed from its lineup file.

## Path parameters

- `contest_id` integer, required

## Query parameters

- `format` string
- `slot` string
- `position` string
- `min_ownership` number, double

## Response `200`

Actual player ownership of one contest, one row per player and roster slot

- DFSContestsOwnershipDfsContestOwnershipResponse
  - `_metadata` object, nullable: The preview notice, sent only when the answer is cut to 5 rows: a caller without a paid plan on a contest that is not a free flagship. Absent otherwise.
    - `message` string, required: What the plan opens, with the pricing link.
    - `required_tier` string, required: The plan that opens the whole table (pro).
    - `total_actual_records` integer, required: The rows of the answer before the cut.
  - `contest` object, required: The contest.
    - `contest_id` integer, required: Internal contest ID.
    - `external_id` integer, required: Operator contest ID.
    - `game_type` string, required: CLASSIC, SHOWDOWN or SINGLE_GAME.
    - `name` string, required: Contest name.
    - `operator` string, required: DraftKings or FanDuel.
    - `slate_id` integer, required: Internal slate ID.
  - `ownership` object[], required: One row per player and roster slot, the highest actual_ownership first.
    - `actual_ownership` number, double, required: lineups / lineups_used, a ratio from 0 to 1 with 4 decimals.
    - `contest_id` integer, required: The contest that the row comes from. Always the contest in the path.
    - `entry_count` integer, nullable: Entries that the operator lists for the contest.
    - `lineups` integer, required: Lineups that hold the player in this slot.
    - `lineups_used` integer, required: Lineups that the ownership of this contest was computed from.
    - `name` string, nullable: Player name.
    - `operator_player_id` string, nullable: The operator's player ID (DraftKings or FanDuel).
    - `player_id` integer, nullable: Our player ID. Null when the player is not resolved.
    - `position` string, nullable: Natural position of the player (for example WR), also on a CPT or MVP row.
    - `salary` integer, nullable: Salary of the slot.
    - `slate_player_id` integer, required: dfs.slate_players id of the seat row.
    - `slot` 'CPT' | 'MVP' | 'FLEX', nullable: Roster slot of the row. Null on a classic contest.
    - `team` string, nullable: Team abbreviation.
    - `total_ownership` number, double, required: Ownership of the player in any slot. Equals actual_ownership on a classic contest.
  - `reason` 'contest_not_final' | 'in_game_format' | 'league_not_computed' | 'no_lineups' | 'actuals_not_recomputed', nullable: Why the answer holds no rows. Null when it holds rows.

## Other responses

- `400`: An unknown format or slot, a min_ownership outside 0 to 1, or an operator external contest ID in the path
- `404`: Contest not found

## Changes

- **2026-10-19** `add5fe9d1374`: 1 warning
  - added the new `league_not_computed` enum value to the `reason` response property for the response status `200`

[Operation history](https://skmtc.dev/stat-api/apis/sports-db-public-api/changes/api/v1/dfs/contests/:contest_id/ownership/get.md)

---

[API](https://skmtc.dev/stat-api/apis/sports-db-public-api.md) · [All operations](https://skmtc.dev/stat-api/apis/sports-db-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/stat-api/apis/sports-db-public-api/revisions/23b66b957723?raw)
