Skip to content

Monitoring ​

Monitors, their results and uptime, and deploy markers.

Common tasks

Only in the app: Nothing. Monitors can be fully managed with a token.

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.

Attention summary ​

Get your attention summary preview ​

When your next “needs you” summary for this organization is due, how it is delivered, and a preview of up to 10 items it would contain. receives is false when you have turned the summary off, and available is false when it cannot be put together right now.

GET/organizations/{organization}/attention-summary
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/attention-summary" \
  -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/attention-summary" -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/attention-summary', [
    '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/attention-summary",
    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/attention-summary', {
  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/attention-summary", 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
{
  "hour": null,
  "organisation_hour": 10,
  "next_at": "2026-01-16T10:00:00+00:00",
  "via": "email",
  "telegram": true,
  "receives": true,
  "available": true,
  "count": 13,
  "new": 13,
  "will_send": true,
  "items": [
    {
      "title": "northwind-labs.com will not renew itself",
      "detail": "Expires Jan 24, 2026 and auto-renew is off.",
      "route": "/domains/14",
      "severity": "warning",
      "new": true
    },
    {
      "title": "northwind.shop will not renew itself",
      "detail": "Expires Jan 26, 2026 and auto-renew is off.",
      "route": "/domains/10",
      "severity": "warning",
      "new": true
    }
  ]
}
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

Deploy events ​

List deploys for a monitor or server ​

The deploys linked to one monitor (monitor) or server (server) between from and to; the window defaults to the 24 hours before to, which defaults to now. Also lists the repositories linked to it.

GET/organizations/{organization}/deploy-events
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.

Query parameters
monitorintegeroptional

This field is required when server is not present.

serverintegeroptional

This field is required when monitor is not present.

fromstring, nullableoptional

Must be a valid date.

tostring, nullableoptional

Must be a valid date.

Request

sh
curl "https://api.infranest.io/api/organizations/42/deploy-events" \
  -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/deploy-events" -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/deploy-events', [
    '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/deploy-events",
    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/deploy-events', {
  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/deploy-events", 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
{
  "data": [],
  "links": [],
  "receives_deploys": true,
  "manage_path": "/integrations/github"
}
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


Get what a deploy changed ​

The commits and pull requests since the previous successful deploy to the same place. Returns first: true when there is no earlier deploy to compare with, and unavailable: true when GitHub could not say.

GET/organizations/{organization}/deploy-events/{deployEvent}/changes
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.

deployEventintegerrequired

The deploy event's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/deploy-events/1/changes" \
  -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/deploy-events/1/changes" -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/deploy-events/1/changes', [
    '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/deploy-events/1/changes",
    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/deploy-events/1/changes', {
  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/deploy-events/1/changes", 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
{
  "first": true
}
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


List repositories that have deployed ​

Each repository and environment that has already reported a deploy to your organization, up to 500.

GET/organizations/{organization}/deploy-events/sources
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/deploy-events/sources" \
  -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/deploy-events/sources" -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/deploy-events/sources', [
    '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/deploy-events/sources",
    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/deploy-events/sources', {
  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/deploy-events/sources", 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
{
  "data": [
    {
      "repository": "northwind-cloud/app",
      "environment": "production"
    },
    {
      "repository": "northwind-cloud/storefront",
      "environment": "production"
    }
  ]
}
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

Your links between a repository and a monitor, server or tag, each with its newest deploy. Pass monitor to list only that monitor’s own links; deploys_connected says whether anything can report deploys to your organization.

GET/organizations/{organization}/deploy-links
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/deploy-links" \
  -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/deploy-links" -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/deploy-links', [
    '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/deploy-links",
    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/deploy-links', {
  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/deploy-links", 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
{
  "data": [
    {
      "id": 1,
      "repository": "northwind-cloud/app",
      "kind": "deployment",
      "environment": "production",
      "workflow": null,
      "branch": null,
      "target_type": "monitor",
      "target_id": 2,
      "target_name": "App — northwind-app.dev",
      "last_deploy_at": "2026-01-15T11:18:00+00:00",
      "has_deployments": true,
      "checking": true
    },
    {
      "id": 2,
      "repository": "northwind-cloud/storefront",
      "kind": "deployment",
      "environment": "production",
      "workflow": null,
      "branch": null,
      "target_type": "monitor",
      "target_id": 4,
      "target_name": "Checkout flow",
      "last_deploy_at": "2026-01-15T11:17:00+00:00",
      "has_deployments": true,
      "checking": true
    }
  ],
  "deploys_connected": true,
  "source": {
    "key": "github",
    "label": "GitHub"
  }
}
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


Create a deploy link ​

Links deploys of a repository to a monitor, server or tag (target_type and target_id). kind chooses what counts as a deploy: deployment (optionally for one environment), workflow (a workflow file, optionally on one branch) or release; earlier deploys are imported in the background.

POST/organizations/{organization}/deploy-links
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.

Bodyapplication/json
repositorystringrequired

Must not be greater than 255 characters.

environmentstring, nullableoptional

Must not be greater than 255 characters.

target_typestringrequired
target_idintegerrequired
kindstring, nullableoptional

What counts as a deploy. A workflow is named by its file, as GitHub's API addresses it.

workflowstring, nullableoptional

This field is required when kind is workflow. Must match the regex /^[\w.-]+\.ya?ml$/. Must not be greater than 255 characters.

branchstring, nullableoptional

Must not be greater than 255 characters.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/deploy-links" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"repository":"northwind-cloud/app","target_type":"server","target_id":1}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "repository": "northwind-cloud/app",
  "target_type": "server",
  "target_id": 1
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/deploy-links" -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/deploy-links', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'repository' => 'northwind-cloud/app',
        'target_type' => 'server',
        'target_id' => 1,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/deploy-links",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "repository": "northwind-cloud/app",
        "target_type": "server",
        "target_id": 1,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/deploy-links', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "repository": "northwind-cloud/app",
    "target_type": "server",
    "target_id": 1
  }),
})
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/deploy-links", strings.NewReader(`{"repository":"northwind-cloud/app","target_type":"server","target_id":1}`))
	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": 3,
  "repository": "northwind-cloud/app",
  "kind": "deployment",
  "environment": null,
  "workflow": null,
  "branch": null,
  "target_type": "server",
  "target_id": 1,
  "target_name": "web-01",
  "last_deploy_at": "2026-01-15T11:18:00+00:00",
  "has_deployments": true,
  "checking": true
}
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 repository 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": {
    "repository": [
      "The repository 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


Removes the link, so its deploys no longer appear on that monitor, server or tag.

DELETE/organizations/{organization}/deploy-links/{deployLink}
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.

deployLinkintegerrequired

The deploy link's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/deploy-links/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/deploy-links/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/deploy-links/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/deploy-links/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/deploy-links/1', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/deploy-links/1", 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
{
  "ok": true
}
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": "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
429 rate_limited


Whether GitHub has any deployment for repository, so you can tell before linking one that never deploys. has_deployments is null when GitHub could not be asked.

GET/organizations/{organization}/deploy-links/check
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/deploy-links/check" \
  -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/deploy-links/check" -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/deploy-links/check', [
    '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/deploy-links/check",
    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/deploy-links/check', {
  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/deploy-links/check", 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
{
  "has_deployments": 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.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


The monitors, servers and tags a deploy link can point at, by ID and name.

GET/organizations/{organization}/deploy-links/targets
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/deploy-links/targets" \
  -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/deploy-links/targets" -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/deploy-links/targets', [
    '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/deploy-links/targets",
    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/deploy-links/targets', {
  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/deploy-links/targets", 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
{
  "monitors": [
    {
      "id": 3,
      "name": "API health"
    },
    {
      "id": 2,
      "name": "App — northwind-app.dev"
    }
  ],
  "servers": [
    {
      "id": 13,
      "name": "analytics-01"
    },
    {
      "id": 3,
      "name": "api-01"
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing"
    },
    {
      "id": 4,
      "name": "Internal"
    }
  ]
}
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

Deploy tokens ​

List deploy tokens ​

Your deploy tokens, newest first, with their name, creator, the monitors each token applies to, whether a signature is required and when each token was last used. Token secrets are never returned.

GET/organizations/{organization}/deploy-tokens
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/deploy-tokens" \
  -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/deploy-tokens" -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/deploy-tokens', [
    '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/deploy-tokens",
    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/deploy-tokens', {
  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/deploy-tokens", 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,
    "name": "CI — deploy hook",
    "created_by": 1,
    "last_used_at": "2026-01-11T12:00:00.000000Z",
    "monitor_ids": [],
    "require_signature": true,
    "created_at": "2026-01-15T12:00:00.000000Z",
    "creator": {
      "id": 1,
      "name": "Alex Rivera",
      "analytics_id": null
    }
  },
  {
    "id": 2,
    "name": "Staging redeploy",
    "created_by": 1,
    "last_used_at": "2025-12-27T12:00:00.000000Z",
    "monitor_ids": [],
    "require_signature": false,
    "created_at": "2026-01-15T12:00:00.000000Z",
    "creator": {
      "id": 1,
      "name": "Alex Rivera",
      "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.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

Email DNS monitors ​

Preview email DNS monitors for a domain ​

Looks up the MX, SPF and DMARC records the domain in domain publishes and returns the DNS monitors that would watch those records. Nothing is created; resolved is false when the lookup failed.

GET/organizations/{organization}/email-dns-monitors
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/email-dns-monitors" \
  -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/email-dns-monitors" -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/email-dns-monitors', [
    '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/email-dns-monitors",
    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/email-dns-monitors', {
  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/email-dns-monitors", 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
{
  "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

No success response is recorded for this endpoint yet.


Create email DNS monitors for a domain ​

Creates one DNS monitor for each MX, SPF and DMARC record the domain in domain publishes right now, and queues a first check of each. Either every monitor is created or none is: the request is refused when the domain publishes none of those records or the monitors would exceed your plan.

POST/organizations/{organization}/email-dns-monitors
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.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/email-dns-monitors" \
  -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/email-dns-monitors" -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/email-dns-monitors', [
    '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/email-dns-monitors",
    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/email-dns-monitors', {
  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/email-dns-monitors", 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
{
  "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

No success response is recorded for this endpoint yet.

External services ​

List external services ​

The third-party services you can watch: the curated catalogue plus any you added yourself. Each comes with its status page address, overall status, components and when it was last polled.

GET/organizations/{organization}/external-services
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/external-services" \
  -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/external-services" -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/external-services', [
    '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/external-services",
    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/external-services', {
  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/external-services", 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": 16,
    "name": "Anthropic",
    "status_url": "https://status.anthropic.com",
    "schema": null,
    "overall_status": "unknown",
    "components": null,
    "is_curated": true,
    "last_polled_at": null
  },
  {
    "id": 19,
    "name": "Atlassian",
    "status_url": "https://status.atlassian.com",
    "schema": null,
    "overall_status": "unknown",
    "components": null,
    "is_curated": true,
    "last_polled_at": 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.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

Monitoring ​

List active probe regions ​

The regions that currently have at least one active probe, as a sorted list of region names. Use these values when choosing where a monitor runs.

GET/monitoring/active-regions
Scope monitoring.readRead only
Authorizationheader
Authorizationstringrequired

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

Request

sh
curl "https://api.infranest.io/api/monitoring/active-regions" \
  -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/monitoring/active-regions" -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/monitoring/active-regions', [
    '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/monitoring/active-regions",
    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/monitoring/active-regions', {
  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/monitoring/active-regions", 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
[]
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": "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
429 rate_limited

Monitoring checks ​

List monitors ​

A paginated list of your monitors with their type, target, interval, current status, 24-hour uptime and a 24-hour status chart, plus status counts in meta. Filter with search, type, kind (own or external), status, enabled and tag, and sort with sort and dir; pass all=true for a plain unpaginated list of every monitor.

GET/organizations/{organization}/monitoring-checks
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/monitoring-checks" \
  -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/monitoring-checks" -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/monitoring-checks', [
    '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/monitoring-checks",
    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/monitoring-checks', {
  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/monitoring-checks", 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": 3,
      "organization_id": 1,
      "name": "API health",
      "type": "http",
      "target": "https://api.northwind.com/health",
      "enabled": true,
      "settings": [],
      "last_status": "up",
      "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 200 — OK",
      "consecutive_failures": 0,
      "flap_threshold": 2,
      "last_status_changed_at": "2026-01-14T12:00: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",
      "alert_channels_count": 0,
      "uptime_24h": "0.0",
      "uptime_chart_24h": [
        "up",
        "up"
      ],
      "in_maintenance": false,
      "effective_interval_seconds": 300,
      "interval_minutes": 5,
      "tags": [
        {
          "id": 5,
          "name": "Northwind Retail",
          "color": "#0ea5e9",
          "pivot": {
            "taggable_type": "App\\Models\\MonitoringCheck",
            "taggable_id": 3,
            "tag_id": 5
          }
        },
        {
          "id": 1,
          "name": "Production",
          "color": "#ef4444",
          "pivot": {
            "taggable_type": "App\\Models\\MonitoringCheck",
            "taggable_id": 3,
            "tag_id": 1
          }
        }
      ]
    },
    {
      "id": 2,
      "organization_id": 1,
      "name": "App — northwind-app.dev",
      "type": "http",
      "target": "https://northwind-app.dev",
      "enabled": true,
      "settings": [],
      "last_status": "up",
      "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 200 — OK",
      "consecutive_failures": 0,
      "flap_threshold": 2,
      "last_status_changed_at": "2026-01-14T12:00: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",
      "alert_channels_count": 0,
      "uptime_24h": "0.0",
      "uptime_chart_24h": [
        "up",
        "up"
      ],
      "in_maintenance": false,
      "effective_interval_seconds": 300,
      "interval_minutes": 5,
      "tags": [
        {
          "id": 6,
          "name": "Northwind Platform",
          "color": "#14b8a6",
          "pivot": {
            "taggable_type": "App\\Models\\MonitoringCheck",
            "taggable_id": 2,
            "tag_id": 6
          }
        },
        {
          "id": 1,
          "name": "Production",
          "color": "#ef4444",
          "pivot": {
            "taggable_type": "App\\Models\\MonitoringCheck",
            "taggable_id": 2,
            "tag_id": 1
          }
        }
      ]
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/monitoring-checks?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/monitoring-checks?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/monitoring-checks?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/monitoring-checks",
  "per_page": 25,
  "prev_page_url": null,
  "to": 13,
  "total": 13,
  "meta": {
    "locked_ids": [],
    "counts": {
      "total": 13,
      "up": 10,
      "down": 1,
      "degraded": 1,
      "paused": 1,
      "silenced": 0,
      "pending": 0
    },
    "tags": [
      {
        "id": 6,
        "name": "Northwind Platform",
        "color": "#14b8a6"
      },
      {
        "id": 5,
        "name": "Northwind Retail",
        "color": "#0ea5e9"
      }
    ]
  }
}
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


Create a monitor ​

Creates a monitor and queues its first check. Pass external_service_id instead of a target to watch a third-party status page; a heartbeat monitor gets its own ping URL as its target. Refused when the monitor count, interval, check type or regions are beyond your plan.

POST/organizations/{organization}/monitoring-checks
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.

Bodyapplication/json
namestringrequired

Must not be greater than 255 characters.

typestringrequired

One of: http, port, ssl, dns, keyword, redirect, ping, api, heartbeat, third_party

external_service_idinteger, nullableoptional
external_component_idsarrayoptional

Must not be greater than 255 characters.

external_alerts_enabledboolean, nullableoptional
targetstringrequired

Must not be greater than 500 characters.

interval_secondsintegeroptional

One of: 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 86400

enabledbooleanoptional
pagerduty_down_severitystringoptional

One of: critical, error, warning, info

pagerduty_degraded_severitystringoptional

One of: critical, error, warning, info

flap_thresholdintegeroptional

Must be at least 1. Must not be greater than 10.

region_consensus_thresholdinteger, nullableoptional

Must be at least 1. Must not be greater than 10.

preferred_regionsarrayoptional
probe_modestringoptional

One of: any, all

ip_versionstringoptional

One of: ipv4, ipv6, prefer_ipv4, prefer_ipv6

slow_response_msinteger, nullableoptional

Must be at least 50. Must not be greater than 30000.

ssl_check_enabledbooleanoptional
ssl_expiry_daysinteger, nullableoptional

Must be at least 1. Must not be greater than 90.

settingsobjectoptional

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"Checkout API","type":"http","target":"https://example.com/health","interval":300}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "name": "Checkout API",
  "type": "http",
  "target": "https://example.com/health",
  "interval": 300
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks" -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/monitoring-checks', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'name' => 'Checkout API',
        'type' => 'http',
        'target' => 'https://example.com/health',
        'interval' => 300,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/monitoring-checks",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "name": "Checkout API",
        "type": "http",
        "target": "https://example.com/health",
        "interval": 300,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Checkout API",
    "type": "http",
    "target": "https://example.com/health",
    "interval": 300
  }),
})
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/monitoring-checks", strings.NewReader(`{"name":"Checkout API","type":"http","target":"https://example.com/health","interval":300}`))
	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
{
  "last_status": "unknown",
  "enabled": true,
  "pagerduty_down_severity": "critical",
  "pagerduty_degraded_severity": "warning",
  "name": "Checkout API",
  "type": "http",
  "target": "https://example.com/health",
  "organization_id": 1,
  "server_id": null,
  "server_link": null,
  "settings": [],
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "created_at": "2026-01-15T12:00:00.000000Z",
  "id": 15,
  "alert_channels_count": 0,
  "interval_minutes": 0,
  "tags": []
}
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 a monitor ​

One monitor with its settings, alert channels, tags, dependencies, maintenance windows, the status pages it appears on, its 30 most recent results and the interval it actually runs at under your plan.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1" \
  -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/monitoring-checks/1" -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/monitoring-checks/1', [
    '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/monitoring-checks/1",
    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/monitoring-checks/1', {
  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/monitoring-checks/1", 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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": true,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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",
  "results_count": 576,
  "alert_channels_count": 0,
  "status_pages": [
    {
      "id": 1,
      "name": "Northwind Cloud Status",
      "slug": "northwind",
      "is_public": true,
      "display_name": "Website"
    }
  ],
  "recent_statuses": [
    "up",
    "up"
  ],
  "recent_results": [
    {
      "status": "up",
      "checked_at": "2026-01-15T09:35:00Z",
      "region": null
    },
    {
      "status": "up",
      "checked_at": "2026-01-15T09:40:00Z",
      "region": null
    }
  ],
  "pagerduty_oncall": [],
  "released_address": null,
  "effective_interval_seconds": 300,
  "interval_minutes": 5,
  "alert_channels": [],
  "tags": [
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\MonitoringCheck",
        "taggable_id": 1,
        "tag_id": 5
      }
    },
    {
      "id": 1,
      "name": "Production",
      "color": "#ef4444",
      "pivot": {
        "taggable_type": "App\\Models\\MonitoringCheck",
        "taggable_id": 1,
        "tag_id": 1
      }
    }
  ],
  "parent_checks": [],
  "child_checks": [],
  "maintenance_windows": [
    {
      "id": 2,
      "organization_id": 1,
      "name": "Load balancer certificate rotation",
      "description": "Replaced the certificate on web-lb and reloaded the listeners.",
      "starts_at": "2026-01-06T01:00:00.000000Z",
      "ends_at": "2026-01-06T01:30:00.000000Z",
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "recurrence_type": "none",
      "recurrence_days": null,
      "start_time": null,
      "duration_minutes": null,
      "suppress_alerts": true,
      "status": "completed",
      "notified_at": null,
      "source": "manual",
      "deploy_id": null,
      "deleted_at": null,
      "purge_after": null,
      "purge_reminder_sent_at": null,
      "deleted_by_id": null,
      "deleted_by_label": null,
      "deletion_reason": null,
      "created_by": null,
      "checks": [],
      "tags": []
    },
    {
      "id": 1,
      "organization_id": 1,
      "name": "Database cluster upgrade",
      "description": "Rolling upgrade of the PostgreSQL primary and its replica. Brief API slowdowns are possible; no downtime is expected.",
      "starts_at": "2026-01-18T02:00:00.000000Z",
      "ends_at": "2026-01-18T03:00:00.000000Z",
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "recurrence_type": "none",
      "recurrence_days": null,
      "start_time": null,
      "duration_minutes": null,
      "suppress_alerts": true,
      "status": "scheduled",
      "notified_at": null,
      "source": "manual",
      "deploy_id": null,
      "deleted_at": null,
      "purge_after": null,
      "purge_reminder_sent_at": null,
      "deleted_by_id": null,
      "deleted_by_label": null,
      "deletion_reason": null,
      "created_by": null,
      "checks": [],
      "tags": []
    }
  ],
  "latest_ssl_certificate": {
    "id": 1,
    "organization_id": 1,
    "source": "probe",
    "monitoring_check_id": 1,
    "domain_id": 1,
    "cloud_server_id": null,
    "provider_credential_id": null,
    "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9",
    "subject": "northwind.com",
    "issuer": "Let's Encrypt (R3)",
    "serial": "2395BA42",
    "sans": [
      "northwind.com",
      "www.northwind.com"
    ],
    "not_before": "2025-12-30T12:00:00.000000Z",
    "not_after": "2026-03-30T12:00:00.000000Z",
    "purpose": "tls_server",
    "key_algo": "rsa",
    "key_bits": 2048,
    "sig_algo": "SHA256-RSA",
    "trust": "public",
    "validation": "DV",
    "is_wildcard": false,
    "is_multi_san": true,
    "managed": true,
    "renewal_source": "Let's Encrypt (R3)",
    "classification_override": null,
    "status": "valid",
    "superseded_by_id": null,
    "dismissed_at": null,
    "deployment_locations": [
      {
        "endpoint": "northwind.com:443",
        "last_seen": "2026-01-15T11:50:00+00:00",
        "first_seen": "2026-01-08T12:00:00+00:00"
      }
    ],
    "owner": null,
    "notes": null,
    "first_seen_at": "2025-11-16T12:00:00.000000Z",
    "last_seen_at": "2026-01-15T06:00:00.000000Z",
    "created_at": "2026-01-15T12:00:00.000000Z",
    "updated_at": "2026-01-15T12:00:00.000000Z",
    "subject_org": null,
    "subject_location": null,
    "chain": [
      {
        "subject": "northwind.com",
        "issuer": "Let's Encrypt (R3)",
        "is_ca": false,
        "self_signed": false,
        "not_after": "2026-03-30T12:00:00+00:00",
        "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9"
      },
      {
        "subject": "Let's Encrypt (R3)",
        "issuer": "ISRG Root X1",
        "is_ca": true,
        "self_signed": false,
        "not_after": "2030-01-15T12:00:00+00:00",
        "fingerprint": "e04ca19ed66485fb479283c98fbfb4cda1ab67de1965304902bec3f6a55a2c8e"
      }
    ],
    "chain_status": "trusted",
    "sources": [
      {
        "source": "probe",
        "last_seen": "2026-01-15T06:00:00+00:00",
        "first_seen": "2025-11-16T12:00:00+00:00"
      }
    ],
    "crl_url": null,
    "ocsp_url": null,
    "caa_status": "ok",
    "caissuer_url": "http://r3.i.lencr.org/",
    "no_auto_merge": false,
    "price_yearly": "0.00",
    "price_source": "manual",
    "price_currency": "EUR",
    "billing_interval": "yearly",
    "interval_count": 1,
    "renewal_type": "automatic",
    "renewal_type_basis": "guess",
    "served_status": "served",
    "served_checked_at": "2026-01-15T11:50:00.000000Z",
    "subscription_ends_at": null,
    "seller": null,
    "role": null,
    "ct_finding": null,
    "owner_user_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.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 a monitor ​

Changes only the fields you send; keys inside settings are merged rather than replaced. Refused when a new interval, check type or set of regions is beyond your plan.

PUT/organizations/{organization}/monitoring-checks/{monitoringCheck}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Bodyapplication/json
namestringoptional

Must not be greater than 255 characters.

server_idinteger, nullableoptional

Must match an existing stored value.

server_link_autobooleanoptional
typestringoptional

One of: http, port, ssl, dns, keyword, redirect, ping, api, heartbeat, third_party

external_component_idsarrayoptional

Must not be greater than 255 characters.

external_alerts_enabledbooleanoptional
targetstringoptional

Must not be greater than 500 characters.

interval_secondsintegeroptional

One of: 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 86400

enabledbooleanoptional
pagerduty_down_severitystringoptional

One of: critical, error, warning, info

pagerduty_degraded_severitystringoptional

One of: critical, error, warning, info

flap_thresholdintegeroptional

Must be at least 1. Must not be greater than 10.

region_consensus_thresholdinteger, nullableoptional

Must be at least 1. Must not be greater than 10.

preferred_regionsarrayoptional
probe_modestringoptional

One of: any, all

ip_versionstringoptional

One of: ipv4, ipv6, prefer_ipv4, prefer_ipv6

slow_response_msinteger, nullableoptional

Must be at least 50. Must not be greater than 30000.

ssl_check_enabledbooleanoptional
ssl_expiry_daysinteger, nullableoptional

Must be at least 1. Must not be greater than 90.

settingsobjectoptional

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/monitoring-checks/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"interval_seconds":300}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "interval_seconds": 300
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/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('PUT', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'interval_seconds' => 300,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "interval_seconds": 300,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "interval_seconds": 300
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/monitoring-checks/1", strings.NewReader(`{"interval_seconds":300}`))
	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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": true,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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",
  "alert_channels_count": 1,
  "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": "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
422 validation_failed
429 rate_limited


Delete a monitor ​

Permanently deletes the monitor. A monitor locked because it is over your plan’s limit cannot be deleted this way.

DELETE/organizations/{organization}/monitoring-checks/{monitoringCheck}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/monitoring-checks/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/monitoring-checks/1", 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

text
No content.
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": "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
429 rate_limited


List what an external service affects ​

For a monitor that watches a third-party status page: the DNS zones, domains, monitors and servers of yours that depend on that service. Each has a source of manual (linked by you) or auto (zones and domains at the matching provider, detected by InfraNest).

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/affected
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected" \
  -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/monitoring-checks/1/affected" -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/monitoring-checks/1/affected', [
    '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/monitoring-checks/1/affected",
    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/monitoring-checks/1/affected', {
  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/monitoring-checks/1/affected", 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
{
  "provider": null,
  "resources": []
}
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


Link a resource to an external service ​

Records that one of your resources, given by resource_type and resource_id, depends on the third-party service this monitor watches. Only works on monitors that watch a third-party status page.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/affected
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Bodyapplication/json
resource_typestringrequired
resource_idintegerrequired

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"resource_type":"<resource_type>","resource_id":16}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "resource_type": "<resource_type>",
  "resource_id": 16
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected" -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/monitoring-checks/1/affected', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'resource_type' => '<resource_type>',
        'resource_id' => 16,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "resource_type": "<resource_type>",
        "resource_id": 16,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "resource_type": "<resource_type>",
    "resource_id": 16
  }),
})
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/monitoring-checks/1/affected", strings.NewReader(`{"resource_type":"<resource_type>","resource_id":16}`))
	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
{
  "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 resource type 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": {
    "resource_type": [
      "The resource type 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

No success response is recorded for this endpoint yet.


Unlink a resource from an external service ​

Removes a resource you linked to the third-party service this monitor watches. Automatically detected links cannot be removed this way.

DELETE/organizations/{organization}/monitoring-checks/{monitoringCheck}/affected/{type}/{resourceId}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

typeintegerrequired

The type's ID.

resourceIdintegerrequired

The resource id's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/monitoring-checks/1/affected/1/1", 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
{
  "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": "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
429 rate_limited

No success response is recorded for this endpoint yet.


Get a monitor’s uptime and response times for a period ​

Totals for one window: uptime_percent (the share of the time no confirmed outage covered, the figure the app shows), up_percent (the share of checks that came back up), checks by outcome, p50 and p95 response time in milliseconds, and the number and minutes of unplanned incidents. Pick period (24h, 7d, 30d or 90d, default 24h) or set from and to (ISO 8601, at most 366 days apart; longer is refused with range_too_large); the window starts on the hour from falls in. Pass region for one probe region, where uptime_percent is the share of checks that were up. Response times over more than one hour or probe are averaged from hourly figures, weighted by the number of checks, so they are close rather than exact. uptime_percent is null when nothing was measured.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/aggregates
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Query parameters
periodstringoptional

24h, 7d, 30d or 90d. Default 24h; ignored when from or to is sent.

fromstringoptional

Start of the window, ISO 8601; rounded down to the hour.

tostringoptional

End of the window, ISO 8601; default now.

regionstringoptional

Only checks from probes in this region.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/aggregates" \
  -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/monitoring-checks/1/aggregates" -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/monitoring-checks/1/aggregates', [
    '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/monitoring-checks/1/aggregates",
    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/monitoring-checks/1/aggregates', {
  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/monitoring-checks/1/aggregates", 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
{
  "monitoring_check_id": 1,
  "period": "24h",
  "from": "2026-01-14T12:00:00Z",
  "to": "2026-01-15T12:00:00Z",
  "region": null,
  "uptime_percent": null,
  "up_percent": 100,
  "checks": {
    "total": 288,
    "up": 288,
    "degraded": 0,
    "down": 0
  },
  "response_time_ms": {
    "p50": 180,
    "p95": 288
  },
  "incidents": {
    "count": 0,
    "down_minutes": 0
  }
}
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


Attach an alert channel to a monitor ​

Sends this monitor’s alerts to the alert channel in alert_channel_id, which must belong to your organization. Refused if the channel is already attached.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/alerts
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Bodyapplication/json
alert_channel_idintegerrequired

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"alert_channel_id":1}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "alert_channel_id": 1
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts" -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/monitoring-checks/1/alerts', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'alert_channel_id' => 1,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "alert_channel_id": 1,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "alert_channel_id": 1
  }),
})
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/monitoring-checks/1/alerts", strings.NewReader(`{"alert_channel_id":1}`))
	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,
  "organization_id": 1,
  "name": "Ops team — email",
  "type": "email",
  "settings": {
    "email": "ops@northwind.example"
  },
  "enabled": true,
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "subscriptions": [
    "monitoring_down",
    "monitoring_recovered"
  ],
  "is_personal": false,
  "user_id": null,
  "format": "html",
  "last_sent_at": null,
  "purge_after": null,
  "purge_reminder_sent_at": null,
  "deleted_by_id": null,
  "deleted_by_label": null,
  "deletion_reason": null,
  "consecutive_failures": 0,
  "last_failure_at": null,
  "last_error": null,
  "last_error_type": null,
  "broken_since": null,
  "broken_notified_at": null,
  "broken_notify_count": 0,
  "awaiting_confirmation_at": null,
  "categories": null,
  "telegram_link_id": null,
  "telegram_chat_id": null,
  "slack_installation_id": null,
  "slack_channel_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 alert channel id 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": {
    "alert_channel_id": [
      "The alert channel id 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


Detach an alert channel from a monitor ​

Stops sending this monitor’s alerts to the channel. A monitor with no channels left keeps running, but no channel receives its alerts.

DELETE/organizations/{organization}/monitoring-checks/{monitoringCheck}/alerts/{alertChannel}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

alertChannelintegerrequired

The alert channel's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/monitoring-checks/1/alerts/1", 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

text
No content.
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": "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
429 rate_limited


Copy a monitor ​

Creates a copy named with “(copy)” appended, with the same settings but no history. The copy starts paused, and counts against your plan like any new monitor.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/clone
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/clone" \
  -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/monitoring-checks/1/clone" -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/monitoring-checks/1/clone', [
    '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/monitoring-checks/1/clone",
    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/monitoring-checks/1/clone', {
  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/monitoring-checks/1/clone", 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
{
  "organization_id": 1,
  "name": "Marketing site (copy)",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": false,
  "settings": [],
  "deleted_at": null,
  "flap_threshold": 2,
  "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": 1,
  "server_link": "inferred",
  "pagerduty_down_severity": "critical",
  "pagerduty_degraded_severity": "warning",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "created_at": "2026-01-15T12:00:00.000000Z",
  "id": 16,
  "alert_channels_count": 0,
  "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


List a monitor’s dependencies ​

The monitors this one depends on (parents) and the monitors that depend on it (children), each with its name, type, target and current status.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/dependencies
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies" \
  -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/monitoring-checks/1/dependencies" -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/monitoring-checks/1/dependencies', [
    '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/monitoring-checks/1/dependencies",
    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/monitoring-checks/1/dependencies', {
  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/monitoring-checks/1/dependencies", 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
{
  "parents": [],
  "children": []
}
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


Add a monitor dependency ​

Pass parent_check_id to make this monitor depend on another, or child_check_id to make another depend on it. Both monitors must be yours, and a dependency on itself or one that would form a loop is refused.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/dependencies
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Bodyapplication/json
parent_check_idinteger, nullableoptional

This field is required when child_check_id is not present. Must match an existing stored value.

child_check_idinteger, nullableoptional

This field is required when parent_check_id is not present. Must match an existing stored value.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"child_check_id":3}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "child_check_id": 3
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies" -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/monitoring-checks/1/dependencies', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'child_check_id' => 3,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "child_check_id": 3,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "child_check_id": 3
  }),
})
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/monitoring-checks/1/dependencies", strings.NewReader(`{"child_check_id":3}`))
	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
{
  "parent_check_id": 1,
  "child_check_id": 3,
  "organization_id": 1,
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "created_at": "2026-01-15T12:00:00.000000Z",
  "id": 2
}
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 parent check id 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": {
    "parent_check_id": [
      "The parent check id 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 a monitor dependency ​

Removes the dependency between the two monitors, in whichever direction it runs.

DELETE/organizations/{organization}/monitoring-checks/{monitoringCheck}/dependencies/{otherCheck}
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.

monitoringCheckintegerrequired

The monitoring check's ID.

otherCheckintegerrequired

The other check's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/monitoring-checks/1/dependencies/1", 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
{
  "message": "Deleted."
}
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": "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
429 rate_limited


List a monitor’s incidents ​

The monitor’s 20 most recent incidents, newest first, with their status, impact, start and end times and duration.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/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/monitoring-checks/1/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/monitoring-checks/1/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/monitoring-checks/1/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/monitoring-checks/1/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/monitoring-checks/1/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
[
  {
    "id": 2,
    "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
  }
]
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


Edit a monitor incident ​

Changes an incident’s description, or marks it as planned with is_planned, which takes it out of uptime figures and the status page’s incident history. Incidents imported from a third-party status page cannot be edited.

PATCH/organizations/{organization}/monitoring-checks/{monitoringCheck}/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.

monitoringCheckintegerrequired

The monitoring check's ID.

incidentintegerrequired

The incident's ID.

Bodyapplication/json
descriptionstring, nullableoptional

Must not be greater than 2000 characters.

is_plannedboolean, nullableoptional

Request

sh
curl -X PATCH "https://api.infranest.io/api/organizations/42/monitoring-checks/1/incidents/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"description":"Caused by an expired upstream certificate.","is_planned":false}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "description": "Caused by an expired upstream certificate.",
  "is_planned": false
}
'@
Invoke-RestMethod -Method Patch -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/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/monitoring-checks/1/incidents/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'description' => 'Caused by an expired upstream certificate.',
        'is_planned' => false,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.patch(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/incidents/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "description": "Caused by an expired upstream certificate.",
        "is_planned": False,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/incidents/1', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "description": "Caused by an expired upstream certificate.",
    "is_planned": false
  }),
})
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/monitoring-checks/1/incidents/1", strings.NewReader(`{"description":"Caused by an expired upstream certificate.","is_planned":false}`))
	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": 2,
  "monitoring_check_id": 1,
  "started_at": "2026-01-09T11:45:00.000000Z",
  "resolved_at": "2026-01-09T12:00:00.000000Z",
  "duration_seconds": 900,
  "cause": null,
  "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": "Caused by an expired upstream certificate.",
  "is_planned": false,
  "title": "Brief marketing-site blip",
  "status": "resolved",
  "impact": "minor",
  "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 description 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": {
    "description": [
      "The description 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


Pause a monitor ​

Stops the monitor from running until you resume it, and returns the updated monitor.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/pause
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/pause" \
  -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/monitoring-checks/1/pause" -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/monitoring-checks/1/pause', [
    '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/monitoring-checks/1/pause",
    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/monitoring-checks/1/pause', {
  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/monitoring-checks/1/pause", 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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": false,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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


Get who an outage alert would reach ​

Whether an outage on this monitor would reach anybody right now: state is ok, nobody or failing, with the alert channels it would use, how many members get the status email, and whether it would escalate.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/reach
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/reach" \
  -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/monitoring-checks/1/reach" -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/monitoring-checks/1/reach', [
    '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/monitoring-checks/1/reach",
    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/monitoring-checks/1/reach', {
  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/monitoring-checks/1/reach", 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
{
  "state": "ok",
  "channels": [
    {
      "id": 1,
      "name": "Ops team — email",
      "type": "email",
      "failing": false
    },
    {
      "id": 2,
      "name": "On-call — critical only",
      "type": "email",
      "failing": false
    }
  ],
  "members": 4,
  "escalation": {
    "via": "pagerduty"
  }
}
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


List a monitor’s check results ​

The monitor’s check results, newest first. With resolution=raw (the default) each result is one check by one probe, filterable by status; individual results are kept for 3 days. With resolution=hour or day each row sums one hour or one day across probes: checks by outcome (checks_up, checks_degraded for slow checks, checks_down for failures), up_percent and the p50 and p95 response times, reaching back as far as your plan keeps history. Set the window with from and to (ISO 8601; default: everything kept for raw, the last 24 hours for hours, the last 30 days for days), narrow it to one probe region, and page with page and per_page (up to 500, default 50). A range longer than the resolution allows — 3 days raw, 31 days by hour, 366 days by day — is refused with range_too_large. window repeats the range that was applied.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/results
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Query parameters
resolutionstringoptional

raw (each check, the default), hour or day (summed across probes).

fromstringoptional

Start of the window, ISO 8601.

tostringoptional

End of the window, ISO 8601; default now.

statusstringoptional

Raw results only: only this status (up, down, degraded).

regionstringoptional

Only results from probes in this region.

per_pageintegeroptional

Rows per page, 1 to 500. Default 50.

pageintegeroptional

Page number, from 1.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/results" \
  -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/monitoring-checks/1/results" -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/monitoring-checks/1/results', [
    '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/monitoring-checks/1/results",
    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/monitoring-checks/1/results', {
  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/monitoring-checks/1/results", 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": 1,
      "monitoring_check_id": 1,
      "status": "up",
      "response_time_ms": 180,
      "status_code": 200,
      "message": "HTTP 200 — OK",
      "checked_at": "2026-01-15T12:00:00.000000Z",
      "meta": null,
      "probe_id": null,
      "is_failover": false,
      "failover_from_region": null,
      "ssl_fingerprint": null,
      "ssl_expires_at": null,
      "scheduled_for": null,
      "suppressed_by_probe": false,
      "reason_code": null,
      "reason_params": null
    },
    {
      "id": 2,
      "monitoring_check_id": 1,
      "status": "up",
      "response_time_ms": 191,
      "status_code": 200,
      "message": "HTTP 200 — OK",
      "checked_at": "2026-01-15T11:55:00.000000Z",
      "meta": null,
      "probe_id": null,
      "is_failover": false,
      "failover_from_region": null,
      "ssl_fingerprint": null,
      "ssl_expires_at": null,
      "scheduled_for": null,
      "suppressed_by_probe": false,
      "reason_code": null,
      "reason_params": null
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/monitoring-checks/1/results?page=1",
  "from": 1,
  "last_page": 12,
  "last_page_url": "http://localhost/api/organizations/1/monitoring-checks/1/results?page=12",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/monitoring-checks/1/results?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": "http://localhost/api/organizations/1/monitoring-checks/1/results?page=2",
  "path": "http://localhost/api/organizations/1/monitoring-checks/1/results",
  "per_page": 50,
  "prev_page_url": null,
  "to": 50,
  "total": 576,
  "window": {
    "from": null,
    "to": null,
    "resolution": "raw"
  }
}
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


Resume a monitor ​

Starts a paused monitor again, queues a check straight away and returns the updated monitor.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/resume
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/resume" \
  -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/monitoring-checks/1/resume" -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/monitoring-checks/1/resume', [
    '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/monitoring-checks/1/resume",
    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/monitoring-checks/1/resume', {
  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/monitoring-checks/1/resume", 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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": true,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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


Run a monitor now ​

Queues an immediate check of the monitor and answers 202 straight away; the result appears in its results once the check has run. Limited by your plan’s hourly allowance of manual checks.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/run
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/run" \
  -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/monitoring-checks/1/run" -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/monitoring-checks/1/run', [
    '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/monitoring-checks/1/run",
    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/monitoring-checks/1/run', {
  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/monitoring-checks/1/run", 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
{
  "message": "Check queued."
}
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


Silence a monitor’s alerts ​

Mutes the monitor’s alerts for duration_minutes (1 to 10,080), or until you unsilence it when you leave that out. The monitor keeps running.

POST/organizations/{organization}/monitoring-checks/{monitoringCheck}/silence
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Bodyapplication/json
duration_minutesinteger, nullableoptional

Must be at least 1. Must not be greater than 10080.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"duration_minutes":60}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "duration_minutes": 60
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence" -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/monitoring-checks/1/silence', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'duration_minutes' => 60,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "duration_minutes": 60,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "duration_minutes": 60
  }),
})
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/monitoring-checks/1/silence", strings.NewReader(`{"duration_minutes":60}`))
	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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": true,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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": "2026-01-15T13:00:00.000000Z",
  "silenced_by": 1,
  "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 duration minutes 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": {
    "duration_minutes": [
      "The duration minutes 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


Unsilence a monitor’s alerts ​

Lifts a silence straight away so the monitor’s alerts are sent again, and returns the updated monitor.

DELETE/organizations/{organization}/monitoring-checks/{monitoringCheck}/silence
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence', {
  method: 'DELETE',
  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("DELETE", "https://api.infranest.io/api/organizations/42/monitoring-checks/1/silence", 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,
  "organization_id": 1,
  "name": "Marketing site",
  "type": "http",
  "target": "https://northwind.com",
  "enabled": true,
  "settings": [],
  "last_status": "up",
  "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 200 — OK",
  "consecutive_failures": 0,
  "flap_threshold": 2,
  "last_status_changed_at": "2026-01-14T12:00: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": "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
429 rate_limited


Get a monitor’s uptime and response-time stats ​

Uptime for the last 24 hours, 7 days and 30 days, incident counts, response-time figures and chart series for the chosen period (24h, 7d or 30d, default 24h). Pass region to narrow the figures to one probe region; the regions with data are listed in regions.

GET/organizations/{organization}/monitoring-checks/{monitoringCheck}/stats
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.

monitoringCheckintegerrequired

The monitoring check's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/monitoring-checks/1/stats" \
  -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/monitoring-checks/1/stats" -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/monitoring-checks/1/stats', [
    '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/monitoring-checks/1/stats",
    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/monitoring-checks/1/stats', {
  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/monitoring-checks/1/stats", 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
{
  "uptime": {
    "24h": null,
    "7d": null,
    "30d": null
  },
  "chart_data": [
    {
      "time": "2026-01-14T12:00:00+00:00",
      "avg": 176,
      "min": 164,
      "max": 186
    },
    {
      "time": "2026-01-14T13:00:00+00:00",
      "avg": 167,
      "min": 154,
      "max": 178
    }
  ],
  "uptime_chart_data": [
    {
      "time": "2026-01-14T12:00:00+00:00",
      "up": 12,
      "total": 12,
      "degraded": 0,
      "down_seconds": 0,
      "status": "up"
    },
    {
      "time": "2026-01-14T13:00:00+00:00",
      "up": 12,
      "total": 12,
      "degraded": 0,
      "down_seconds": 0,
      "status": "up"
    }
  ],
  "period": "24h",
  "response_time": {
    "avg": 180,
    "min": 137,
    "max": 223
  },
  "incident_stats": {
    "24h": {
      "count": 0,
      "down_minutes": 0
    },
    "7d": {
      "count": 1,
      "down_minutes": 15
    },
    "30d": {
      "count": 1,
      "down_minutes": 15
    }
  },
  "regions": [],
  "region": null,
  "chart_by_region": 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.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

Status ​

Get the current status of everything ​

Everything in your organization as it stands right now, in one call: every monitor with its status (up, down, degraded, paused or unknown), when it was last checked and its 24-hour uptime; every server with its state, whether its agent is reporting (null when no agent is installed) and how many of its alert rules are breaching; the open incidents; the maintenance windows running now; and counts of each in summary. Pass tag (a tag ID) to narrow it to monitors and servers with that tag, their incidents, and maintenance that carries the tag or covers them. servers is null when the token has no Cloud scope or your role cannot see servers.

GET/organizations/{organization}/status
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.

Query parameters
tagintegeroptional

Only monitors and servers with this tag, and what concerns them.

Request

sh
curl "https://api.infranest.io/api/organizations/42/status" \
  -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/status" -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/status', [
    '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/status",
    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/status', {
  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/status", 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
{
  "generated_at": "2026-01-15T12:00:00Z",
  "tag": null,
  "summary": {
    "monitors": {
      "total": 13,
      "up": 10,
      "down": 1,
      "degraded": 1,
      "paused": 1,
      "unknown": 0
    },
    "servers": {
      "total": 14,
      "running": 12,
      "agent_not_reporting": 0,
      "breaching": 0
    },
    "open_incidents": 1,
    "active_maintenance": 0
  },
  "monitors": [
    {
      "id": 3,
      "name": "API health",
      "type": "http",
      "status": "up",
      "enabled": true,
      "silenced": false,
      "last_checked_at": "2026-01-15T11:58:00Z",
      "uptime_24h": 0
    },
    {
      "id": 2,
      "name": "App — northwind-app.dev",
      "type": "http",
      "status": "up",
      "enabled": true,
      "silenced": false,
      "last_checked_at": "2026-01-15T11:58:00Z",
      "uptime_24h": 0
    }
  ],
  "servers": [
    {
      "id": 13,
      "name": "analytics-01",
      "status": "stopped",
      "monitoring_enabled": false,
      "agent_reporting": null,
      "breaching_alerts": 0
    },
    {
      "id": 3,
      "name": "api-01",
      "status": "running",
      "monitoring_enabled": true,
      "agent_reporting": true,
      "breaching_alerts": 0
    }
  ],
  "incidents": [
    {
      "id": 1,
      "title": "Checkout returning 503",
      "status": "investigating",
      "impact": "major",
      "started_at": "2026-01-15T11:20:00Z",
      "acknowledged_at": null,
      "monitoring_check_id": 4,
      "server_id": null
    }
  ],
  "maintenance": []
}
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

Uptime report ​

Get the monthly uptime report ​

Uptime per monitor for one calendar month, with downtime, incidents, longest outage and the basis of each figure. Pass month as YYYY-MM (default: the last full month) and tag to limit it to monitors with that tag.

GET/organizations/{organization}/uptime-report
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/uptime-report" \
  -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/uptime-report" -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/uptime-report', [
    '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/uptime-report",
    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/uptime-report', {
  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/uptime-report", 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
{
  "month": "2025-12",
  "closed": true,
  "days_in_month": 31,
  "checks": [
    {
      "id": 3,
      "name": "API health",
      "type": "http",
      "target": "https://api.northwind.com/health",
      "uptime_pct": 99.951,
      "downtime_minutes": 22,
      "incidents": 1,
      "longest_outage_minutes": 22,
      "monitored_minutes": 44640,
      "days_with_data": 31,
      "planned_minutes_excluded": 0,
      "probes": [],
      "started_monitoring": "2026-01-15"
    },
    {
      "id": 2,
      "name": "App — northwind-app.dev",
      "type": "http",
      "target": "https://northwind-app.dev",
      "uptime_pct": 100,
      "downtime_minutes": 0,
      "incidents": 0,
      "longest_outage_minutes": 0,
      "monitored_minutes": 44640,
      "days_with_data": 31,
      "planned_minutes_excluded": 0,
      "probes": [],
      "started_monitoring": "2026-01-15"
    }
  ],
  "summary": {
    "checks": 13,
    "checks_measured": 12,
    "worst_uptime_pct": 99.951,
    "mean_uptime_pct": 99.996,
    "incidents": 1,
    "downtime_minutes": 22
  },
  "findings": [
    {
      "key": "uptimeReport.findings.worst",
      "params": {
        "check": "API health",
        "percent": 99.951,
        "minutes": 22,
        "n": 1
      },
      "tone": "warning"
    },
    {
      "key": "uptimeReport.findings.unmeasured",
      "params": {
        "n": 1,
        "total": 13
      },
      "tone": "warning"
    }
  ],
  "generated_at": "2026-01-15T12:00:00+00:00",
  "months": [
    {
      "month": "2025-02",
      "closed": true,
      "checks": 13,
      "checks_measured": 0,
      "worst_uptime_pct": null,
      "mean_uptime_pct": null,
      "incidents": 0,
      "downtime_minutes": 0
    },
    {
      "month": "2025-03",
      "closed": true,
      "checks": 13,
      "checks_measured": 0,
      "worst_uptime_pct": null,
      "mean_uptime_pct": null,
      "incidents": 0,
      "downtime_minutes": 0
    }
  ],
  "applied_filters": []
}
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


Download the monthly uptime report as CSV ​

The same report as a CSV file, one row per monitor. Takes the same month and tag parameters, and every download is recorded in your audit log.

GET/organizations/{organization}/uptime-report/export
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/uptime-report/export" \
  -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/uptime-report/export" -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/uptime-report/export', [
    '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/uptime-report/export",
    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/uptime-report/export', {
  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/uptime-report/export", 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

text
The month's uptime report as CSV.
Content-Type: text/csv
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