Skip to content
Erik Hennerfors edited this page Oct 13, 2026 · 2 revisions

Create, read, update and delete issues (Issues API).

Issues track incidents, whether opened by Cronitor when a monitor fails or by you, for example for planned maintenance. They can be published on your status pages.

Getting a client

Issues are managed through an IIssuesClient: CronitorClient.Issues on the static class, injected after .ConfigureCronitor(), or created with new IssuesClient("apiKey"). See Setup for each. The examples below use issuesClient.

Methods

Each method has a sync and an async (…Async) version. All of them throw when Cronitor answers with an error.

Method Returns Description
ListAsync(int page = 1) ListIssueResponse One page of issues
ListAsync(ListIssueRequest request) ListIssueResponse One page of issues, filtered and ordered
GetAsync(string key) Issue One issue
CreateAsync(CreateIssueRequest request) Issue Creates an issue
UpdateAsync(UpdateIssueRequest request) Issue Updates an issue
DeleteAsync(string key) Deletes an issue

Issue is in Cronitor.Models, the requests in Cronitor.Requests, and IssueSeverity, IssueState and IssueOrder in Cronitor.Constants.

Create

using Cronitor.Constants;
using Cronitor.Models;
using Cronitor.Requests;

var issue = new Issue
{
    Name = "Database maintenance",
    Severity = IssueSeverity.Maintenance,
    State = IssueState.Identified,
    Environment = "production",
    StatusPages = new[] { "status" },
    Updates = new[]
    {
        new Cronitor.Models.Issues.Event
        {
            Message = "The database is being upgraded; reports may be delayed.",
            State = IssueState.Identified
        }
    }
};

var created = await issuesClient.CreateAsync(new CreateIssueRequest(issue));
Console.WriteLine(created.Key);

It returns the issue as Cronitor stored it, with its Key.

The update class is Cronitor.Models.Issues.Event. Write the full name: Cronitor.Models has an Event class of its own, for monitor events.

Properties

Properties you can set:

Property Description
Name The display name, used in alerts, in Cronitor and on status pages.
Severity IssueSeverity.Outage, .MinorOutage, .DegradedPerformance, .Maintenance, .Operational or .MissingData.
State IssueState.Unresolved, .Investigating, .Identified, .Monitoring, .Resolved or .Update.
Environment The key of the environment the issue belongs to.
Started When the issue started, as an ISO 8601 timestamp, e.g. 2026-06-02T09:39:31Z.
AssignedTo A member of your Cronitor team, who is notified by email.
StatusPages Keys of the status pages to publish the issue on.
AffectedComponents Keys of the status page components the issue affects. They must belong to a page in StatusPages.
Updates Updates posted to the issue. Only each update's Message and State are sent.

Key is set by Cronitor when the issue is created.

Properties Cronitor sets, read from an issue you get or list: Ended, Duration (in seconds; both null while the issue is open), CreatedBy, CreatedAt, UpdatedAt, and, when listing with the matching option, Monitors and Alerts. They're never sent back to Cronitor.

Get

var issue = await issuesClient.GetAsync("issueKey");

Console.WriteLine($"{issue.Name}: {issue.State} since {issue.Started}");
foreach (var update in issue.Updates)
{
    Console.WriteLine($"{update.Timestamp:u} {update.State} {update.Message}");
}

List

ListAsync returns one page of issues. Items holds the issues; Page, PageSize, PageCount and Total tell you where you are:

var response = await issuesClient.ListAsync();

foreach (var issue in response.Items)
{
    Console.WriteLine($"{issue.Key}: {issue.Name} ({issue.Severity})");
}

To filter and order, pass a ListIssueRequest. Filters you don't set aren't sent:

using Cronitor.Constants;
using Cronitor.Requests;

var request = new ListIssueRequest
{
    Environment = "production",
    Time = "7d",
    OrderBy = IssueOrder.StartedDescending,
    WithMonitorDetails = true
};
request.States.Add(IssueState.Unresolved);
request.Jobs.Add("nightly-backup");

var response = await issuesClient.ListAsync(request);
foreach (var issue in response.Items)
{
    foreach (var monitor in issue.Monitors)
    {
        Console.WriteLine($"{issue.Name} affects {monitor.Name}");
    }
}
Property Filters by
Page, PageSize The page, and the number of issues per page (up to 1000)
States State, e.g. IssueState.Unresolved
Severities Severity, e.g. IssueSeverity.Outage
Jobs, Checks, Heartbeats, Sites Keys of the monitors of that type the issue affects
Types Monitor type, e.g. MonitorType.Job
Groups Keys of monitor groups
Tags Monitor tags
Components Keys of status page components
StatusPage Key of a status page
Environment Environment key
Search Text in the issue's name, or in an affected monitor's name or key
Time How far back to look, e.g. "24h", "7d" or "30d"
OrderBy IssueOrder.StartedAscending, .StartedDescending, .RelevanceAscending, .RelevanceDescending

These options add details to each issue in the response:

Option Fills
WithMonitorDetails = true Monitors: the affected monitors, with their state and group
WithAlertDetails = true Alerts: the alerts Cronitor sent for the issue
WithStatusPageDetails = true Nothing yet: Cronitor sends status page details, but Issue has no property for them
WithComponentDetails = true Nothing yet: Cronitor sends component details, but Issue has no property for them

Update

UpdateIssueRequest takes the issue's key and an Issue with the properties to change. Properties that are null aren't sent, so build a new Issue with only what changes:

using Cronitor.Constants;
using Cronitor.Models;
using Cronitor.Requests;

var changes = new Issue
{
    State = IssueState.Resolved,
    Updates = new[]
    {
        new Cronitor.Models.Issues.Event
        {
            Message = "The upgrade is done.",
            State = IssueState.Resolved
        }
    }
};

var issue = await issuesClient.UpdateAsync(new UpdateIssueRequest("issueKey", changes));

Delete

await issuesClient.DeleteAsync("issueKey");

Clone this wiki locally