Repository navigation
Issues
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.
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.
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.
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 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.
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}");
}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 |
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));await issuesClient.DeleteAsync("issueKey");Getting started
Telemetry
Management
Integrations