> ## 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.

# PHP SDK

> Call the incident.io API from PHP with a method for every endpoint and a model for every request and response.

The PHP SDK gives you a client for the whole incident.io API. There's a method for every endpoint and a model class for every request and response, all generated from our OpenAPI specification. HTTP goes through [Guzzle 7](https://docs.guzzlephp.org/), so timeouts, proxies, and middleware work the way you're used to.

It requires PHP 8.1 or later, with the `curl`, `json`, and `mbstring` extensions.

## Installing

```bash theme={null}
composer require incident-io/sdk-php
```

## Your first request

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

```php theme={null}
use IncidentIo\Api\IncidentsV2Api;
use IncidentIo\Configuration;

$config = (new Configuration())->setAccessToken(getenv('INCIDENT_API_KEY'));
$incidents = new IncidentsV2Api(config: $config);

$result = $incidents->incidentsV2List(pageSize: 25);
foreach ($result->getIncidents() as $incident) {
    echo $incident->getReference(), ' ', $incident->getName(), "\n";
}
```

## How endpoints work

There's one class per API group under `IncidentIo\Api`, named for the group and its version (`IncidentsV2Api`, `SeveritiesV1Api`, `CatalogV3Api`), and one model class per request and response under `IncidentIo\Model`. Each endpoint has four methods:

* **`incidentsV2List(...)`** returns the response model.
* **`incidentsV2ListWithHttpInfo(...)`** returns `[$model, $statusCode, $headers]`.
* **`incidentsV2ListAsync(...)`** and **`incidentsV2ListAsyncWithHttpInfo(...)`** return Guzzle promises for the same.

Pass parameters by name, as in the example above. The API adds optional parameters as a backwards-compatible change, and a new one can land before the ones you use. Named arguments are unaffected, but positional calls would shift.

Models take an array of properties, keyed by the camelCase property name:

```php theme={null}
use IncidentIo\Model\IncidentsCreatePayloadV2;

$incident = $incidents->incidentsV2Create(new IncidentsCreatePayloadV2([
    'idempotencyKey' => 'deploy-2026-09-23-01',
    'name' => 'Checkout is returning 500s',
    'visibility' => IncidentsCreatePayloadV2::VISIBILITY__PUBLIC,
]))->getIncident();
```

## Pagination

List endpoints return a page and a cursor. Pass `paginationMeta.after` back as `after` until it's empty:

```php theme={null}
$after = null;
do {
    $page = $incidents->incidentsV2List(pageSize: 100, after: $after);
    foreach ($page->getIncidents() as $incident) {
        // ...
    }
    $after = $page->getPaginationMeta()?->getAfter();
} while ($after !== null && $after !== '');
```

## Filtering

Filter parameters take an operator and a list of values, as an array:

```php theme={null}
$incidents->incidentsV2List(
    statusCategory: ['one_of' => ['live', 'learning']],
    customField: ['01FCNDV6P870EA6S7TK1DSYDG0' => ['one_of' => ['01FCNDV6P870EA6S7TK1DSYDG1']]],
);
```

Each parameter's description lists the operators it accepts.

## Errors

A response outside 2xx throws `IncidentIo\ApiException`. Its code is the HTTP status, and the body is the API's JSON error:

```php theme={null}
use IncidentIo\ApiException;

try {
    $incidents->incidentsV2Show(id: '01NOTREAL');
} catch (ApiException $e) {
    echo $e->getCode(), "\n";           // 404
    echo $e->getResponseBody(), "\n";   // {"type":"not_found","status":404,"request_id":"...","errors":[...]}
}
```

A network failure also throws `ApiException`, with code 0. If you contact us about a failed request, include the `request_id` from the body.

## Configuration

`Configuration` holds the API key, the base URL (`setHost`, which defaults to `https://api.incident.io`), and the user agent (`setUserAgent`). The first argument to every Api class is a Guzzle client, so timeouts, proxies, and middleware are Guzzle options:

```php theme={null}
use GuzzleHttp\Client;

$incidents = new IncidentsV2Api(new Client(['timeout' => 10]), $config);
```

The SDK doesn't retry. When you hit the [rate limit](/api-reference/introduction#rate-limits), the API answers with a `429` and a `Retry-After` header in seconds. Guzzle's retry middleware can handle this, and the [README](https://github.com/incident-io/sdk-php#retries) has a ready-made example.

## Enum values

Enum values are constants on the model that uses them, such as `ActionV1::STATUS_COMPLETED`, and the properties themselves are plain strings. We add enum values as a backwards-compatible change, so the SDK accepts values it doesn't know: a newer value comes through as sent. If you `match` on an enum, give it a `default` arm.

## Deprecated endpoints

Endpoints we've deprecated stay available, but they're marked `@deprecated`, which IDEs and static analysers pick up. Don't go by the version in the name: some `v2` endpoints are deprecated too.

## 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="Packagist" icon="php" href="https://packagist.org/packages/incident-io/sdk-php">
    The `incident-io/sdk-php` package and its versions.
  </Card>

  <Card title="GitHub" icon="github" href="https://github.com/incident-io/sdk-php">
    Source, README, and issues for the PHP 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, Python, Rust, Ruby, and .NET.
  </Card>
</CardGroup>
