> 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/live-data/session-states.md).

# Session states

This guide covers how session states work in the Motorsport API, what fields the State entity contains, and how to use states reliably in your application without hardcoding IDs.

#### When to use this

Use session states when you want to:

* Detect whether a session is scheduled, live, or finished
* Show a status badge on a fixture card
* Gate logic in your application (e.g. only start polling live data when a session is active)
* Filter fixtures by state

#### What a state is

Every fixture has a `state_id` field. This is a foreign key that refers to a State entity. The State entity describes the current lifecycle status of the session.

The State entity has the following fields:

| Field            | Type    | Description                                       |
| ---------------- | ------- | ------------------------------------------------- |
| `id`             | integer | The unique ID of the state                        |
| `state`          | string  | The abbreviation of the state                     |
| `name`           | string  | The full human-readable name of the state         |
| `short_name`     | string  | A short version of the name                       |
| `developer_name` | string  | The recommended stable identifier for use in code |

`developer_name` is the field to use in your application logic. It is the stable, consistent identifier that does not change between API versions. Avoid hardcoding `id` values in conditional logic.

#### Fetching all states

Fetch the full list of states once at startup and cache them locally:

```http
GET https://api.sportmonks.com/v3/motorsport/states
?api_token={your_token}
```

States are reference data that rarely change. Fetching them once and storing them in memory or a local cache saves API calls and means you can resolve any `state_id` instantly without an extra include on every fixture request.

#### Including state on a fixture or livescore

To get the state object alongside a fixture in the same request:

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

Response (partial):

```json
{
  "data": {
    "id": 19408487,
    "name": "Race",
    "state_id": 3,
    "state": {
      "id": 3,
      "state": "LIVE",
      "name": "In Play",
      "short_name": "IP",
      "developer_name": "INPLAY"
    }
  }
}
```

#### Working with the data

**Build a local state lookup**

Fetch states once and build a lookup map so you never need to include `state` on every fixture request:

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

```javascript
const API_TOKEN = 'your_token';

async function buildStateLookup() {
  const response = await fetch(
    `https://api.sportmonks.com/v3/motorsport/states?api_token=${API_TOKEN}`
  );
  const { data } = await response.json();
  return new Map(data.map(s => [s.id, s]));
}

const stateLookup = await buildStateLookup();

function getDeveloperName(stateId) {
  return stateLookup.get(stateId)?.developer_name ?? null;
}
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

API_TOKEN = "your_token"

def build_state_lookup():
    url = "https://api.sportmonks.com/v3/motorsport/states"
    params = {"api_token": API_TOKEN}
    response = requests.get(url, params=params)
    states = response.json()["data"]
    return {s["id"]: s for s in states}

STATE_LOOKUP = build_state_lookup()

def get_developer_name(state_id):
    state = STATE_LOOKUP.get(state_id)
    return state["developer_name"] if state else None
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
function buildStateLookup(string $apiToken): array {
    $url = "https://api.sportmonks.com/v3/motorsport/states?api_token={$apiToken}";
    $response = json_decode(file_get_contents($url), true);
    $lookup = [];
    foreach ($response['data'] as $state) {
        $lookup[$state['id']] = $state;
    }
    return $lookup;
}

$stateLookup = buildStateLookup('your_token');

function getDeveloperName(int $stateId, array $lookup): ?string {
    return $lookup[$stateId]['developer_name'] ?? null;
}
```

{% endtab %}
{% endtabs %}

**Gate live polling on session state**

Use `developer_name` rather than `state_id` in conditional logic so your code is readable and resilient to any future state ID changes:

```python
def should_poll_live(fixture, state_lookup):
    developer_name = get_developer_name(fixture["state_id"])
    return developer_name == "INPLAY"
```

```javascript
function shouldPollLive(fixture, stateLookup) {
  const state = stateLookup.get(fixture.state_id);
  return state?.developer_name === 'INPLAY';
}
```

**Display a human-readable status badge**

```python
def get_status_label(state_id, state_lookup):
    state = state_lookup.get(state_id)
    return state["name"] if state else "Unknown"
```

```javascript
function getStatusLabel(stateId, stateLookup) {
  return stateLookup.get(stateId)?.name ?? 'Unknown';
}
```

#### Common pitfalls

**Hardcoding state IDs.** State IDs are internal integers that are consistent but not guaranteed to be meaningful across contexts. Use `developer_name` in your conditional logic (`"INPLAY"`, `"FT"`, `"NS"`) so the intent is readable and the code is not brittle to any future numbering changes.

**Including `state` on every live poll.** States are reference data that do not change during a session. Fetch them once at startup, build a local lookup, and resolve `state_id` locally. This removes one include from every polling request, reducing payload size and query complexity.

**Assuming `state_id` is set immediately.** Newly created fixtures may have a `null` state\_id before they are assigned a state. Always check for null before looking up state data.

#### Common errors

| Status | Likely cause                                       |
| ------ | -------------------------------------------------- |
| `401`  | Missing or invalid `api_token`                     |
| `404`  | The state ID does not exist in the States endpoint |

#### See also

**Related tutorials**

* [Live sessions](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/live-data/live-sessions)
* [Fixtures](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/fixtures)
* [Filter and select fields - Filtering](https://docs.sportmonks.com/v3/motorsport-api/tutorials-and-guides/tutorials/filter-and-select-fields/filtering)

**Reference**

* [State entity](https://docs.sportmonks.com/v3/motorsport-api/endpoints-and-entities/entities/state.md)
* [Live entity](https://docs.sportmonks.com/v3/motorsport-api/endpoints-and-entities/entities/live.md)

#### FAQ

**Where do I find the full list of state values?** Call `GET https://api.sportmonks.com/v3/motorsport/states?api_token={your_token}` to retrieve every state with its `id`, `name`, `short_name`, and `developer_name`.

**Does a session go from scheduled directly to live?** State transitions depend on the session lifecycle managed on Sportmonks' side. Fetch states periodically and use `developer_name` to respond to transitions rather than polling for a specific ID.

**Is there a state for sessions that have been postponed or cancelled?** The States endpoint returns the full list of possible states. Fetch it to see all values, including any for postponed or cancelled sessions.

**Why does `state` have no include options?** The State entity has no nested includes. All the data you need is on the state object itself.


---

# 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/live-data/session-states.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.
