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

# Python SDK

> Call the incident.io API from Python, sync or async, with typed requests and responses for every endpoint.

The Python SDK gives you a typed client for the whole incident.io API. There's a module for every endpoint and a type for every request and response, all generated from our OpenAPI specification. It ships type annotations, so a type checker like mypy or Pyright can catch mistakes before you run anything.

It requires Python 3.11 or later.

## Installing

```bash theme={null}
pip install incident-io
```

## Your first request

You'll need an API key from **Settings > API keys** (see [API keys](/admin/api-keys)). Then:

```python theme={null}
from incident_io import AuthenticatedClient
from incident_io.api.incidents_v2 import incidents_v2_list
from incident_io.models import IncidentsListResultV2

client = AuthenticatedClient(
    base_url="https://api.incident.io",
    token="my-api-key",
)

result = incidents_v2_list.sync(client=client, page_size=25)
if isinstance(result, IncidentsListResultV2):
    for incident in result.incidents:
        print(incident.reference, incident.name)
```

The `isinstance` check matters. A failed request doesn't raise: it comes back as an `ErrorResponse`, so `result` is one of the two. Your type checker will tell you if you skip the check.

## How endpoints work

Every endpoint is a module with four functions:

* **`sync`** returns the parsed body, or an `ErrorResponse` for a documented error.
* **`sync_detailed`** returns a `Response` with `status_code`, `headers`, and `parsed`. This is the most direct way to tell success from failure.
* **`asyncio`** and **`asyncio_detailed`** are the async versions of the two above, and share the same client.

```python theme={null}
response = incidents_v2_list.sync_detailed(client=client)
if response.status_code != 200:
    raise RuntimeError(f"unexpected status {response.status_code}: {response.content!r}")

result = await incidents_v2_list.asyncio(client=client, page_size=25)
```

## Pagination

List endpoints are cursor-paginated. Read the next cursor from `pagination_meta.after` and pass it back as `after`:

```python theme={null}
from incident_io.types import UNSET, Unset

after: str | Unset = UNSET
while True:
    page = incidents_v2_list.sync(client=client, page_size=100, after=after)
    if not isinstance(page, IncidentsListResultV2):
        raise RuntimeError(f"request failed: {page}")

    for incident in page.incidents:
        print(incident.reference, incident.name)

    # The last page has no cursor to follow.
    if isinstance(page.pagination_meta, Unset) or isinstance(page.pagination_meta.after, Unset):
        break
    after = page.pagination_meta.after
```

Optional fields that the API didn't send are `UNSET` rather than `None`, which is why the check above looks for `Unset`.

## Configuration

`AuthenticatedClient` takes keyword arguments:

```python theme={null}
import httpx

client = AuthenticatedClient(
    base_url="https://api.incident.io",
    token="my-api-key",
    timeout=httpx.Timeout(30.0),             # defaults to httpx's own
    headers={"User-Agent": "my-app/1.0.0"},  # identify your integration
    raise_on_unexpected_status=True,         # raise instead of returning None
    httpx_args={"proxy": "http://localhost:8080"},
)
```

`raise_on_unexpected_status=True` raises `incident_io.errors.UnexpectedStatus` for a status code the schema doesn't document, instead of returning `None`. Documented errors still come back as an `ErrorResponse`.

The client is built on [httpx](https://www.python-httpx.org/). To reuse a connection pool or bring your own transport, pass `httpx_args`, or hand the client a configured instance with `client.set_httpx_client(...)`.

## Deprecated endpoints

Endpoints we've deprecated (for example the `v1` incidents and custom fields endpoints, superseded by `v2`) stay available, but calling one issues a `DeprecationWarning` naming the endpoint. Python hides these by default, so run with `-W default::DeprecationWarning` to see them.

## Versioning

The SDK is kept up to date with the API automatically. Additions to the API are minor versions. A change that would break your code, like a removed field, is released as a new major version, and its release notes list what changed.

## Resources

<CardGroup cols={2}>
  <Card title="PyPI" icon="python" href="https://pypi.org/project/incident-io/">
    The `incident-io` package and its versions.
  </Card>

  <Card title="GitHub" icon="github" href="https://github.com/incident-io/sdk-python">
    Source, README, and issues for the Python SDK.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Endpoints, authentication, rate limits, and errors.
  </Card>

  <Card title="All SDKs" icon="cubes" href="/integrations/sdks">
    Clients for Go, TypeScript, Rust, Ruby, PHP, and .NET.
  </Card>
</CardGroup>
