Skip to content

Alerts and notifications ​

Alert channels, alert rules and notification settings. Read only: changing who gets alerted stays in the app.

Common tasks

Only in the app: Adding or changing alert channels and who gets alerted.

How it works in the app: help article.

Scopes: Read with monitoring.read. 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.

Alert channels ​

List alert destinations ​

Every place the organization sends alerts, such as email, Slack or Telegram, with how many checks use each and how many alerts it missed while it refused messages. Pass personal=1 for only your own personal destinations.

GET/organizations/{organization}/alert-channels
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/alert-channels" \
  -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/alert-channels" -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/alert-channels', [
    '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/alert-channels",
    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/alert-channels', {
  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/alert-channels", 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": "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,
    "checks_count": 0,
    "missed_alerts_count": 0,
    "missed_alerts_min_created_at": null,
    "needs_telegram_link": false
  },
  {
    "id": 2,
    "organization_id": 1,
    "name": "On-call — critical only",
    "type": "email",
    "settings": {
      "email": "oncall@northwind.example",
      "critical_only": true
    },
    "enabled": true,
    "deleted_at": null,
    "created_at": "2026-01-15T12:00:00.000000Z",
    "updated_at": "2026-01-15T12:00:00.000000Z",
    "subscriptions": [
      "monitoring_down",
      "domain_expiry_critical"
    ],
    "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,
    "checks_count": 0,
    "missed_alerts_count": 0,
    "missed_alerts_min_created_at": null,
    "needs_telegram_link": false
  }
]
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 an alert destination ​

One alert destination with the checks that send to it.

GET/organizations/{organization}/alert-channels/{alertChannel}
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.

alertChannelintegerrequired

The alert channel's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/alert-channels/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/alert-channels/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/alert-channels/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/alert-channels/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/alert-channels/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/alert-channels/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": "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,
  "checks_count": 0,
  "checks": []
}
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