> For the complete documentation index, see [llms.txt](https://docs.sportmonks.com/v3/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/enrich-your-response/lineups.md).

# Lineups

This guide shows you how to retrieve the driver lineup for a session - which drivers and teams took part, their car number, grid position, and how to enrich the lineup with full driver and team detail.

#### When to use this

Use the `lineups` include when you want to:

* Display the starting grid for a race or qualifying session
* Build a driver roster for a specific session before results are available
* Resolve a driver's name, number, and team from a fixture without a separate drivers lookup
* Pair lineup data with `results` or `lineups.details` to attach timing and status to each driver

#### The basics

Lineups are not a standalone endpoint. They are retrieved as an include on a fixture:

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups
```

The base lineup entry looks like this:

```json
{
  "id": 14671697707,
  "sport_id": 2,
  "fixture_id": 19408487,
  "player_id": 37920803,
  "team_id": 276189,
  "position_id": 9730,
  "type_id": 11,
  "grid_position": 16,
  "driver_name": "Lewis Hamilton",
  "driver_number": 44
}
```

`player_id` is the driver's ID and matches `participant_id` on results, laps, pitstops, and stints. `driver_number` is the car number, not the driver's ID. `grid_position` is only populated for race-type sessions, since practice and qualifying sessions do not have a starting grid in the same sense.

#### Enriching with driver and team data

The base lineup entry only gives you `driver_name` and `driver_number` as flat strings. To get the full driver entity - image, country, short name, debut metadata - nest the `driver` include:

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups.driver
```

To get the team as well:

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups.driver;lineups.team
```

To go one level deeper and get the driver's country (depth 3, within the limit on the Fixture endpoint):

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups.driver.country
```

See [How to Use Includes in the Motorsport API](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/enrich-your-response/how-to-use-includes-in-the-motorsport-api) for the full depth-limit table per endpoint.

#### Combining lineups with results and details

The lineup itself does not carry timing or status. Pair it with `results` for position, gap, and tyre data:

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups.driver;results
```

For the full set of session-level driver data in one nested object - points, laps, pitstops, fastest lap, status - use `lineups.details` instead of `results`. This is the richer alternative covered in [Retrieving results](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/retrieving-results):

```http
GET https://api.sportmonks.com/v3/motorsport/fixtures/19408487
?api_token={your_token}&include=lineups.details
```

#### Working with the data

**Build a starting grid**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const API_TOKEN = 'your_token';
const FIXTURE_ID = 19408487;

const response = await fetch(
  `https://api.sportmonks.com/v3/motorsport/fixtures/${FIXTURE_ID}?api_token=${API_TOKEN}&include=lineups.driver;lineups.team`
);
const { data: fixture } = await response.json();

const grid = fixture.lineups
  .filter(entry => entry.grid_position !== null)
  .sort((a, b) => a.grid_position - b.grid_position)
  .map(entry => ({
    position: entry.grid_position,
    driver: entry.driver.display_name,
    number: entry.driver_number,
    team: entry.team.name
  }));

console.log(grid);
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

API_TOKEN = "your_token"
FIXTURE_ID = 19408487

url = f"https://api.sportmonks.com/v3/motorsport/fixtures/{FIXTURE_ID}"
params = {
    "api_token": API_TOKEN,
    "include": "lineups.driver;lineups.team"
}

response = requests.get(url, params=params)
fixture = response.json()["data"]

grid = sorted(
    (entry for entry in fixture["lineups"] if entry["grid_position"] is not None),
    key=lambda entry: entry["grid_position"]
)

for entry in grid:
    driver = entry["driver"]["display_name"]
    number = entry["driver_number"]
    team = entry["team"]["name"]
    print(f"{entry['grid_position']}. {driver} (#{number}) - {team}")
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$apiToken = 'your_token';
$fixtureId = 19408487;

$url = "https://api.sportmonks.com/v3/motorsport/fixtures/{$fixtureId}?api_token={$apiToken}&include=lineups.driver;lineups.team";
$response = json_decode(file_get_contents($url), true);
$fixture = $response['data'];

$grid = array_filter($fixture['lineups'], fn($entry) => $entry['grid_position'] !== null);
usort($grid, fn($a, $b) => $a['grid_position'] <=> $b['grid_position']);

foreach ($grid as $entry) {
    echo "{$entry['grid_position']}. {$entry['driver']['display_name']} (#{$entry['driver_number']}) - {$entry['team']['name']}\n";
}
```

{% endtab %}
{% endtabs %}

**Resolve a driver from a result entry**

When working with the `results` include separately from `lineups`, you will often need to match a `participant_id` back to a driver name. Pre-load the lineup once per fixture and build a lookup:

{% tabs %}
{% tab title="First Tab" %}

```javascript
function buildDriverLookup(lineups) {
  return new Map(
    lineups.map(entry => [entry.player_id, {
      name: entry.driver_name,
      number: entry.driver_number,
      teamId: entry.team_id
    }])
  );
}

const driverLookup = buildDriverLookup(fixture.lineups);
const driver = driverLookup.get(resultEntry.participant_id);
```

{% endtab %}

{% tab title="Python" %}

```python
def build_driver_lookup(lineups):
    return {
        entry["player_id"]: {
            "name": entry["driver_name"],
            "number": entry["driver_number"],
            "team_id": entry["team_id"],
        }
        for entry in lineups
    }

driver_lookup = build_driver_lookup(fixture["lineups"])
driver = driver_lookup.get(result_entry["participant_id"])
```

{% endtab %}
{% endtabs %}

This avoids a second API call per result entry, since the lineup is already loaded for the fixture.

#### Common pitfalls

**`grid_position` is `null` for non-race sessions.** Practice and qualifying sessions do not populate this field the same way a race does. Check for `null` before sorting or displaying a grid for these session types.

**`player_id` on a lineup entry matches `participant_id` elsewhere, not `id`.** When joining lineup data with results, laps, pitstops, or stints, match on `lineups[].player_id` against `participant_id` in those responses. They are the same driver ID under different field names depending on the entity.

**`driver_name` and `driver_number` are denormalised flat fields, not the full driver entity.** If you need the driver's image, country, or short name, you must add the `lineups.driver` nested include. The flat fields exist for convenience when you only need a display name.

**Team data is not included by default.** `team_id` is present on the base lineup entry, but the team name, colour, and logo require the `lineups.team` nested include.

**Mixing `lineups.details` and `results` in the same request adds unnecessary payload.** Both return overlapping driver-level data. Use `results` for a lighter response with the most common fields, or `lineups.details` when you need the full type set. Avoid requesting both together unless you specifically need fields only available in one.

#### Common errors

| Status | Likely cause                                                                        |
| ------ | ----------------------------------------------------------------------------------- |
| `401`  | Missing or invalid `api_token`                                                      |
| `404`  | The `fixture_id` does not exist                                                     |
| `422`  | Query complexity exceeded - remove nested includes such as `lineups.driver.country` |

#### See also

**Related tutorials**

* [How to Use Includes in the Motorsport API](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/enrich-your-response/how-to-use-includes-in-the-motorsport-api)
* [Retrieving results](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/retrieving-results)
* [How to Track Lap-by-Lap Timing for a Race](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/enrich-your-response/how-to-track-lap-by-lap-timing-for-a-race)

**Reference**

* [Request Options](https://docs.sportmonks.com/v3/motorsport-api/welcome/request-options)
* [Results and Live Data Type Reference](https://docs.sportmonks.com/v3/motorsport-api/welcome/results-and-live-data-type-reference)

**Related entities**

* [Driver](https://docs.sportmonks.com/v3/motorsport-api/endpoints-and-entities/entities)
* [Team](https://docs.sportmonks.com/v3/motorsport-api/endpoints-and-entities/entities)
* [Fixture](https://docs.sportmonks.com/v3/motorsport-api/endpoints-and-entities/entities)

#### FAQ

**Can I get lineups without fetching the whole fixture?** No. Lineups are only available as a nested include on a fixture (or anywhere fixtures themselves are included, such as a season or stage). There is no standalone lineups endpoint.

**Does the lineup change after the session starts?** The lineup for a race is generally fixed at the start, but driver changes (rare, due to injury or disqualification before the session begins) are reflected if you re-fetch the fixture.

**Why is `grid_position` different from `position_id`?** `grid_position` is the starting position for the session. `position_id` is an internal classification field unrelated to finishing or starting order. Use `results` or `lineups.details` with the `POSITION` type for live or finishing position instead.

**How do I get the lineup for an entire season at once?** Nest the include further from the season level: `&include=fixtures.lineups.driver`. Be mindful of the include depth limit on the seasons endpoint before doing this for a full season of fixtures in one call.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/enrich-your-response/lineups.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
