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

# .NET SDK

> Call the incident.io API from C# and .NET with typed requests and responses for every endpoint.

The .NET SDK gives you a typed client for the whole incident.io API. There's a method for every endpoint and a type for every request and response, generated from our OpenAPI specification with [Kiota](https://learn.microsoft.com/en-us/openapi/kiota/). The methods follow the shape of the URL, so it's easy to go from an endpoint in the API reference to the code that calls it.

It targets .NET 8 and .NET 10.

## Installing

```bash theme={null}
dotnet add package IncidentIo
```

## Your first request

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

```csharp theme={null}
using IncidentIo;

var client = new IncidentIoClient("my-api-key");

var result = await client.V2.Incidents.GetAsync(request =>
{
    request.QueryParameters.PageSize = 25;
});

foreach (var incident in result!.Incidents!)
{
    Console.WriteLine($"{incident.Reference} {incident.Name}");
}
```

The client holds an `HttpClient`, so create one and reuse it.

## Finding an endpoint

The methods follow the URL:

* `GET /v2/incidents` is `client.V2.Incidents.GetAsync()`.
* `GET /v2/incidents/{id}` is `client.V2.Incidents[id].GetAsync()`.
* `POST /v2/incidents` is `client.V2.Incidents.PostAsync(body)`.

Path segments are PascalCase, so `/v2/alert_attributes` is `client.V2.AlertAttributes`. Every method is async and takes an optional `CancellationToken`. Query parameters go on `request.QueryParameters`, and request and response types live in `IncidentIo.Models`.

## Pagination

List endpoints are cursor-paginated. Read the next cursor from `PaginationMeta.After` and pass it back:

```csharp theme={null}
string? after = null;

do
{
    var page = await client.V2.Incidents.GetAsync(request =>
    {
        request.QueryParameters.PageSize = 100;
        request.QueryParameters.After = after;
    });

    foreach (var incident in page!.Incidents!)
    {
        Console.WriteLine($"{incident.Reference} {incident.Name}");
    }

    after = page.PaginationMeta?.After;
} while (after != null);
```

## Filtering

Some list endpoints take filters in the form `field[operator]=value`, like `status[one_of]=firing`. The generator can't express these as typed parameters, so the SDK leaves them out. You can still use them: pass them in the URL with `WithUrl`, which keeps authentication and everything else about the request.

```csharp theme={null}
var alerts = await client.V2.Alerts
    .WithUrl("https://api.incident.io/v2/alerts?page_size=25&status[one_of]=firing")
    .GetAsync();
```

Escape values with `Uri.EscapeDataString` if they can contain `&`, `=`, or spaces.

## Errors

A documented error status throws `IncidentIo.Models.ErrorResponse`, which carries the API's error body. Anything else throws Kiota's `ApiException`, which `ErrorResponse` derives from:

```csharp theme={null}
using IncidentIo.Models;
using Microsoft.Kiota.Abstractions;

try
{
    await client.V2.Incidents["01ABC"].GetAsync();
}
catch (ErrorResponse error)
{
    Console.WriteLine($"HTTP {error.ResponseStatusCode}, request {error.RequestId}");
}
catch (ApiException error)
{
    Console.WriteLine($"HTTP {error.ResponseStatusCode}");
}
```

If you contact us about a failed request, include the `RequestId`.

## Configuration

```csharp theme={null}
var client = new IncidentIoClient("my-api-key", new IncidentIoClientOptions
{
    // Defaults to https://api.incident.io. Must be https.
    BaseUrl = "https://api.incident.io",

    // The handler that sends each request, for a proxy or custom TLS.
    InnerHandler = new HttpClientHandler { Proxy = new System.Net.WebProxy("http://proxy:8080") },
});
```

The API key is only ever sent to the configured host. If you need your own `HttpClient`, you can build the client from a Kiota request adapter instead. The [README](https://github.com/incident-io/sdk-net#configuration) shows how.

### Retries

Unlike most of our other SDKs, this one retries for you. Requests that fail with `429`, `503`, or `504` are retried up to three times, honouring the `Retry-After` header the API sends when you hit the [rate limit](/api-reference/introduction#rate-limits).

One thing to watch out for: a retried `POST` can be applied twice if the first attempt reached us before failing. Creating an incident or an escalation takes an `IdempotencyKey` for exactly this reason, so set it.

## Enum values

We add enum values as a backwards-compatible change. When a response carries a value your version of the SDK doesn't know, that property reads as `null` rather than throwing, and the rest of the response is unaffected. Upgrade the package to see the new value.

## Deprecated endpoints

Endpoints we've deprecated stay available and are marked `[Obsolete]`, so the compiler warns at the call site (`CS0618`). Don't go by the version in the name: some `V2` endpoints are deprecated too. If you build with `TreatWarningsAsErrors`, add `CS0618` to `WarningsNotAsErrors` so a newly deprecated endpoint doesn't fail your build.

## 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 type or member, is released as a new major version, and its release notes list what changed.

## Resources

<CardGroup cols={2}>
  <Card title="NuGet" icon="microsoft" href="https://www.nuget.org/packages/IncidentIo">
    The `IncidentIo` package and its versions.
  </Card>

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