Incidents
Incidents: open, update and resolve them.
Common tasks
Only in the app: Nothing. Monitors open incidents; a token can update, annotate and acknowledge them, as the app can.
How it works in the app: help article.
Scopes: Read with monitoring.read, change with monitoring.write. See Tokens and scopes.
Every endpoint below takes a token in the Authorization: Bearer header and answers JSON. Errors use the shared format in Errors. Base address: https://api.infranest.io/api.
Incidents
List incidents
A paginated list of your monitors’ incidents with their monitor, status, impact, latest update and who acknowledged each one, plus counts in meta. period is 24h, 7d (default), 30d or all; filter with status (open, acked or resolved) and search, or pass incident to fetch a single incident whatever its age.
/organizations/{organization}/incidentsmonitoring.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/incidents" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/incidents" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/incidents', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/incidents",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/incidents", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"current_page": 1,
"data": [
{
"id": 2,
"monitoring_check_id": 1,
"source": "monitor",
"title": "Brief marketing-site blip",
"status": "resolved",
"impact": "minor",
"started_at": "2026-01-09T11:45:00.000000Z",
"resolved_at": "2026-01-09T12:00:00.000000Z",
"duration_seconds": 900,
"cause": null,
"description": null,
"external_status": null,
"external_url": null,
"is_planned": false,
"acknowledged_at": null,
"acknowledged_by": null,
"check": {
"id": 1,
"name": "Marketing site",
"type": "http",
"last_status": "up",
"interval_minutes": 0
},
"updates": [
{
"id": 5,
"monitoring_incident_id": 2,
"status": "resolved",
"message": "A CDN configuration change was rolled back and the site recovered. No other services were affected.",
"user_id": null,
"created_at": "2026-01-09T12:00:00.000000Z",
"user": null
}
]
},
{
"id": 1,
"monitoring_check_id": 4,
"source": "monitor",
"title": "Checkout returning 503",
"status": "investigating",
"impact": "major",
"started_at": "2026-01-15T11:20:00.000000Z",
"resolved_at": null,
"duration_seconds": null,
"cause": "Upstream payment gateway timeout",
"description": null,
"external_status": null,
"external_url": null,
"is_planned": false,
"acknowledged_at": null,
"acknowledged_by": null,
"check": {
"id": 4,
"name": "Checkout flow",
"type": "http",
"last_status": "down",
"interval_minutes": 0
},
"updates": [
{
"id": 3,
"monitoring_incident_id": 1,
"status": "monitoring",
"message": "The failover is live and checkout is succeeding again. Watching error rates before we call this resolved.",
"user_id": null,
"created_at": "2026-01-15T11:54:00.000000Z",
"user": null
}
]
}
],
"first_page_url": "http://localhost/api/organizations/1/incidents?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "http://localhost/api/organizations/1/incidents?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "http://localhost/api/organizations/1/incidents?page=1",
"label": "1",
"page": 1,
"active": true
}
],
"next_page_url": null,
"path": "http://localhost/api/organizations/1/incidents",
"per_page": 25,
"prev_page_url": null,
"to": 2,
"total": 2,
"meta": {
"counts": {
"total": 2,
"open": 1,
"acked": 0,
"resolved": 1
}
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Update an incident
Changes an incident’s title, status, impact, description or is_planned. Setting status to resolved resolves an open incident, and any other status reopens a resolved one; incidents imported from a third-party status page cannot be edited.
/organizations/{organization}/incidents/{incident}monitoring.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Bodyapplication/json
titlestring, nullableoptionalMust not be greater than 255 characters.
statusstringoptionalOne of: investigating, identified, monitoring, resolved
impactstringoptionalOne of: critical, major, minor, none
descriptionstring, nullableoptionalMust not be greater than 5000 characters.
is_plannedbooleanoptionalRequest
curl -X PATCH "https://api.infranest.io/api/organizations/42/incidents/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"status":"identified","impact":"major"}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"status": "identified",
"impact": "major"
}
'@
Invoke-RestMethod -Method Patch -Uri "https://api.infranest.io/api/organizations/42/incidents/1" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.infranest.io/api/organizations/42/incidents/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'status' => 'identified',
'impact' => 'major',
],
]);
echo $response->getBody();import os
import requests
response = requests.patch(
"https://api.infranest.io/api/organizations/42/incidents/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"status": "identified",
"impact": "major",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"status": "identified",
"impact": "major"
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("PATCH", "https://api.infranest.io/api/organizations/42/incidents/1", strings.NewReader(`{"status":"identified","impact":"major"}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"monitoring_check_id": 4,
"started_at": "2026-01-15T11:20:00.000000Z",
"resolved_at": null,
"duration_seconds": null,
"cause": "Upstream payment gateway timeout",
"affected_probe_ids": null,
"acknowledged_at": null,
"acknowledged_by": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"description": null,
"is_planned": false,
"title": "Checkout returning 503",
"status": "identified",
"impact": "major",
"source": "monitor",
"server_id": null,
"cloud_server_alert_rule_id": null,
"external_status": null,
"external_url": null,
"alert_rule_state_id": null,
"folded_into": null,
"unstable_at": null,
"unstable_ended_at": null,
"outage_count": 1,
"down_since": null,
"downtime_seconds": 0,
"outages": null,
"acknowledged_by_name": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The title field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"title": [
"The title field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited
Acknowledge an incident
Marks the incident as acknowledged by you, so your team knows someone is on it, and returns it with who acknowledged it.
/organizations/{organization}/incidents/{incident}/acknowledgemonitoring.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/acknowledge" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/incidents/1/acknowledge" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/incidents/1/acknowledge', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/incidents/1/acknowledge",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1/acknowledge', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/incidents/1/acknowledge", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"monitoring_check_id": 4,
"started_at": "2026-01-15T11:20:00.000000Z",
"resolved_at": null,
"duration_seconds": null,
"cause": "Upstream payment gateway timeout",
"affected_probe_ids": null,
"acknowledged_at": "2026-01-15T12:00:00.000000Z",
"acknowledged_by": {
"id": 1,
"first_name": null,
"last_name": null,
"analytics_id": null
},
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"description": null,
"is_planned": false,
"title": "Checkout returning 503",
"status": "investigating",
"impact": "major",
"source": "monitor",
"server_id": null,
"cloud_server_alert_rule_id": null,
"external_status": null,
"external_url": null,
"alert_rule_state_id": null,
"folded_into": null,
"unstable_at": null,
"unstable_ended_at": null,
"outage_count": 1,
"down_since": null,
"downtime_seconds": 0,
"outages": null,
"acknowledged_by_name": null,
"check": {
"id": 4,
"organization_id": 1,
"name": "Checkout flow",
"type": "http",
"target": "https://northwind.com/checkout",
"enabled": true,
"settings": [],
"last_status": "down",
"last_checked_at": "2026-01-15T11:58:00.000000Z",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"last_message": "HTTP 503 — Service Unavailable",
"consecutive_failures": 8,
"flap_threshold": 2,
"last_status_changed_at": "2026-01-15T11:20:00.000000Z",
"consensus_threshold": 1,
"preferred_regions": [
"EU"
],
"probe_mode": "any",
"ip_version": "prefer_ipv4",
"slow_response_ms": null,
"ssl_check_enabled": true,
"ssl_expiry_days": 21,
"heartbeat_uuid": null,
"last_ping_at": null,
"silenced_until": null,
"silenced_by": null,
"is_suppressed_by_parent": false,
"external_service_id": null,
"external_component_ids": null,
"external_alerts_enabled": false,
"region_checked_at": null,
"region_consensus_threshold": null,
"last_reason_code": null,
"last_reason_params": null,
"interval_seconds": 300,
"badge_enabled": false,
"badge_token": null,
"purge_after": null,
"purge_reminder_sent_at": null,
"deleted_by_id": null,
"deleted_by_label": null,
"deletion_reason": null,
"server_id": null,
"server_link": null,
"pagerduty_down_severity": "critical",
"pagerduty_degraded_severity": "warning",
"interval_minutes": 5
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"name": [
"The name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Add a team note to an incident
Adds an internal note in body for your team. Notes never appear on a status page.
/organizations/{organization}/incidents/{incident}/notesmonitoring.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Bodyapplication/json
bodystringrequiredRequest
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/notes" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"body":"Rolled back release 2026.01.15 — error rate back to normal."}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"body": "Rolled back release 2026.01.15 — error rate back to normal."
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/incidents/1/notes" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/incidents/1/notes', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'body' => 'Rolled back release 2026.01.15 — error rate back to normal.',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/incidents/1/notes",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"body": "Rolled back release 2026.01.15 — error rate back to normal.",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1/notes', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"body": "Rolled back release 2026.01.15 — error rate back to normal."
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/incidents/1/notes", strings.NewReader(`{"body":"Rolled back release 2026.01.15 — error rate back to normal."}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"body": "Rolled back release 2026.01.15 — error rate back to normal.",
"via": "app",
"by": "Alex Rivera",
"created_at": "2026-01-15T12:00:00+00:00"
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The body field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"body": [
"The body field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Remove an incident acknowledgement
Clears the acknowledgement so the incident reads as unhandled again.
/organizations/{organization}/incidents/{incident}/unacknowledgemonitoring.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"monitoring_check_id": 4,
"started_at": "2026-01-15T11:20:00.000000Z",
"resolved_at": null,
"duration_seconds": null,
"cause": "Upstream payment gateway timeout",
"affected_probe_ids": null,
"acknowledged_at": null,
"acknowledged_by": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"description": null,
"is_planned": false,
"title": "Checkout returning 503",
"status": "investigating",
"impact": "major",
"source": "monitor",
"server_id": null,
"cloud_server_alert_rule_id": null,
"external_status": null,
"external_url": null,
"alert_rule_state_id": null,
"folded_into": null,
"unstable_at": null,
"unstable_ended_at": null,
"outage_count": 1,
"down_since": null,
"downtime_seconds": 0,
"outages": null,
"acknowledged_by_name": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"name": [
"The name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Get an incident’s timeline
The incident’s public status updates and internal team notes, plus the alert channels that were notified, deploys shortly before it began, who PagerDuty is paging, notes from PagerDuty and tickets opened for it.
/organizations/{organization}/incidents/{incident}/updatesmonitoring.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Request
curl "https://api.infranest.io/api/organizations/42/incidents/1/updates" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/incidents/1/updates" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/incidents/1/updates', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/incidents/1/updates",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1/updates', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/incidents/1/updates", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"updates": [
{
"id": 3,
"monitoring_incident_id": 1,
"status": "monitoring",
"message": "The failover is live and checkout is succeeding again. Watching error rates before we call this resolved.",
"user_id": null,
"created_at": "2026-01-15T11:54:00.000000Z",
"user": null
},
{
"id": 8,
"monitoring_incident_id": 1,
"status": "investigating",
"message": "The provider has acknowledged an incident on their side. We are holding while they work.",
"user_id": 1,
"created_at": "2026-01-15T11:51:00.000000Z",
"user": {
"id": 1,
"first_name": null,
"last_name": null,
"analytics_id": null
}
}
],
"team_notes": [],
"notified": [
"email",
"slack"
],
"deploys": [
{
"id": 9,
"source": "github",
"kind": "deployment",
"workflow": null,
"repository": "northwind-cloud/storefront",
"environment": "production",
"state": "success",
"sha": "f19e6c7000000000000000000000000000000000",
"ref": "main",
"actor": "jordan-k",
"url": "https://github.com/northwind-cloud/storefront/deployments",
"deployed_at": "2026-01-15T11:17:00+00:00"
}
],
"oncall": [],
"pagerduty_notes": [
{
"id": 2,
"author_name": "Alex Rivera",
"content": "Secondary payment route is warmed up — Sam is switching checkout over to it now.",
"created_at": "2026-01-15T11:45:00+00:00"
},
{
"id": 1,
"author_name": "Sam Okoye",
"content": "Payment gateway status page shows degraded API performance in eu-west. Opening a ticket with them.",
"created_at": "2026-01-15T11:26:00+00:00"
}
],
"tickets": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Post an incident update
Posts a public status update with a status and message, and moves the incident to that status (resolved resolves it). Status page subscribers are notified unless you send notify_subscribers: false; incidents imported from a third-party status page cannot be updated.
/organizations/{organization}/incidents/{incident}/updatesmonitoring.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
incidentintegerrequiredThe incident's ID.
Bodyapplication/json
statusstringrequiredOne of: investigating, identified, monitoring, resolved
messagestringrequiredMust not be greater than 5000 characters.
notify_subscribersbooleanoptionalRequest
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/updates" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"status":"monitoring","message":"A fix is out; we are watching checkout recover."}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"status": "monitoring",
"message": "A fix is out; we are watching checkout recover."
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/incidents/1/updates" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/incidents/1/updates', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'status' => 'monitoring',
'message' => 'A fix is out; we are watching checkout recover.',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/incidents/1/updates",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"status": "monitoring",
"message": "A fix is out; we are watching checkout recover.",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/incidents/1/updates', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"status": "monitoring",
"message": "A fix is out; we are watching checkout recover."
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/incidents/1/updates", strings.NewReader(`{"status":"monitoring","message":"A fix is out; we are watching checkout recover."}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"monitoring_incident_id": 1,
"status": "monitoring",
"message": "A fix is out; we are watching checkout recover.",
"user_id": 1,
"created_at": "2026-01-15T12:00:00.000000Z",
"id": 9,
"incident": {
"id": 1,
"monitoring_check_id": 4,
"started_at": "2026-01-15T11:20:00.000000Z",
"resolved_at": null,
"duration_seconds": null,
"cause": "Upstream payment gateway timeout",
"affected_probe_ids": null,
"acknowledged_at": null,
"acknowledged_by": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"description": null,
"is_planned": false,
"title": "Checkout returning 503",
"status": "investigating",
"impact": "major",
"source": "monitor",
"server_id": null,
"cloud_server_alert_rule_id": null,
"external_status": null,
"external_url": null,
"alert_rule_state_id": null,
"folded_into": null,
"unstable_at": null,
"unstable_ended_at": null,
"outage_count": 1,
"down_since": null,
"downtime_seconds": 0,
"outages": null,
"acknowledged_by_name": null
},
"user": {
"id": 1,
"first_name": null,
"last_name": null,
"analytics_id": null
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the monitoring.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "monitoring.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The status field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"status": [
"The status field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited