Skip to content

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.

GET/organizations/{organization}/incidents
Scope monitoring.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/incidents" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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": "&laquo; 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
    }
  }
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

PATCH/organizations/{organization}/incidents/{incident}
Scope monitoring.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Bodyapplication/json
titlestring, nullableoptional

Must not be greater than 255 characters.

statusstringoptional

One of: investigating, identified, monitoring, resolved

impactstringoptional

One of: critical, major, minor, none

descriptionstring, nullableoptional

Must not be greater than 5000 characters.

is_plannedbooleanoptional

Request

sh
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"}'
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

POST/organizations/{organization}/incidents/{incident}/acknowledge
Scope monitoring.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/acknowledge" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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
  }
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

POST/organizations/{organization}/incidents/{incident}/notes
Scope monitoring.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Bodyapplication/json
bodystringrequired

Request

sh
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."}'
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

POST/organizations/{organization}/incidents/{incident}/unacknowledge
Scope monitoring.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/incidents/1/unacknowledge" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

GET/organizations/{organization}/incidents/{incident}/updates
Scope monitoring.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/incidents/1/updates" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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": []
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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.

POST/organizations/{organization}/incidents/{incident}/updates
Scope monitoring.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

incidentintegerrequired

The incident's ID.

Bodyapplication/json
statusstringrequired

One of: investigating, identified, monitoring, resolved

messagestringrequired

Must not be greater than 5000 characters.

notify_subscribersbooleanoptional

Request

sh
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."}'
powershell
$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
<?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();
python
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())
js
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())
go
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

json
{
  "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
  }
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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"
}
json
{
  "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