Uptimeify Docs
Incident management

Channels

List, create, update and delete Incident Management paging channels (webhook, Slack, email), including the write-only handling of webhook URLs and headers.

GET /api/im/channels · POST /api/im/channels · GET /api/im/channels/:id · PATCH /api/im/channels/:id · DELETE /api/im/channels/:id

A channel is a shared paging destination of your organization: a generic webhook, a Slack incoming webhook, or an email address. A channel is either org-wide (teamId: null) or belongs to one team. A channel can be set as the organization's fallback channel in the organization settings, the last resort when an escalation runs out of tiers.

Authentication

Requires the base IM access every endpoint in this API needs (an IM-eligible role admin, editor or responder, or an organization-wide API token; Incident Management must be enabled for the organization). Reading is open to any IM-eligible role. Writing an org-wide channel requires the admin role. Writing a team channel requires the admin role or team-admin membership of that team. An organization-wide API token runs with the role of the user who created it, so a token created by an organization admin can write every channel. Team-admin membership never applies to a token.

Channel types and config

typeRequired config fieldsOptional config fields
webhookwebhookUrlheaders (object of header name to value)
slackwebhookUrlheaders
emailemail
  • webhookUrl must be an http or https URL with a public hostname. Private, loopback and reserved IP addresses, localhost, *.local, *.internal, home.arpa and hostnames without a dot are rejected.
  • headers must not set the Host header.
  • config may be at most 8 KB as JSON. Other keys are stored as sent.

webhookUrl and header values are write-only. They are encrypted at rest and never returned. Every response replaces them: webhookUrl is null and hasWebhookUrl says whether one is stored; headers keeps the header names with null values and hasHeaders says whether any header is stored.

List channels

GET /api/im/channels

Returns all channels of your organization (org-wide and team channels), sorted by name, with the team name resolved.

Example (cURL)

curl -X GET "$BASE_URL/api/im/channels" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

Response

200 OK

[
  {
    "id": 9,
    "organizationId": 1,
    "teamId": 3,
    "teamName": "Platform Team",
    "type": "webhook",
    "name": "Ops webhook",
    "config": {
      "webhookUrl": null,
      "headers": { "X-Api-Key": null },
      "hasWebhookUrl": true,
      "hasHeaders": true
    },
    "isActive": true,
    "createdAt": "2026-09-20T10:00:00.000Z",
    "updatedAt": "2026-09-20T10:00:00.000Z"
  },
  {
    "id": 10,
    "organizationId": 1,
    "teamId": null,
    "teamName": null,
    "type": "email",
    "name": "NOC mailbox",
    "config": { "email": "noc@example.com" },
    "isActive": true,
    "createdAt": "2026-09-20T10:05:00.000Z",
    "updatedAt": "2026-09-20T10:05:00.000Z"
  }
]

Get a channel

GET /api/im/channels/:id

Returns one channel (without teamName) plus a references block that tells you whether it is the organization's fallback channel. A fallback channel cannot be deleted or deactivated.

{
  "id": 10,
  "organizationId": 1,
  "teamId": null,
  "type": "email",
  "name": "NOC mailbox",
  "config": { "email": "noc@example.com" },
  "isActive": true,
  "createdAt": "2026-09-20T10:05:00.000Z",
  "updatedAt": "2026-09-20T10:05:00.000Z",
  "references": {
    "isOrgFallback": true,
    "fallbackOrganizationIds": [1]
  }
}

Create a channel

POST /api/im/channels

Request Body

FieldTypeRequiredDescription
typestringYeswebhook, slack or email.
namestringYesDisplay name, trimmed, max 120 characters.
configobjectYesSee channel types and config.
teamIdinteger | nullNoTeam of your organization, or null/omitted for an org-wide channel.
isActivebooleanNoDefault true. Any value other than true creates an inactive channel.

Example (cURL)

curl -X POST "$BASE_URL/api/im/channels" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "webhook",
    "name": "Ops webhook",
    "teamId": 3,
    "config": {
      "webhookUrl": "https://hooks.example.com/im/7f3a",
      "headers": { "X-Api-Key": "k_live_51b2" }
    }
  }'

Response

200 OK: the created channel, with secrets redacted as described above. The response never echoes the URL or header values you just sent.

Update a channel

PATCH /api/im/channels/:id

Accepts only name, type, config, isActive and teamId; any other key, or an empty body, is a 400. You need write access to the channel's current scope, and, when you change teamId, also to the new scope (moving a channel to org-wide needs the admin role).

config is merged onto the stored config, so you never have to resend secrets you cannot read back:

  • Omit webhookUrl, or send it as null or "", to keep the stored URL. Send a new URL to replace it.
  • If you send headers, it replaces the stored set of header names. A header whose value is null or "" keeps its stored value; a header you leave out is removed.
  • When you change type, the merged config is validated against the new type, e.g. switching an email channel to webhook requires a webhookUrl.
  • Deactivating (isActive: false) the organization's fallback channel is refused with 409.
curl -X PATCH "$BASE_URL/api/im/channels/9" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ops webhook (primary)", "config": { "headers": { "X-Api-Key": null } } }'

200 OK: the updated channel, secrets redacted.

Delete a channel

DELETE /api/im/channels/:id

Refused with 409 while the channel is the organization's fallback channel; point fallbackChannelId in the organization settings elsewhere (or to null) first.

curl -X DELETE "$BASE_URL/api/im/channels/9" \
  -H "Authorization: Bearer $TOKEN"

200 OK

{ "success": true }

Common errors

  • 401 Unauthorized when not authenticated
  • 403 Forbidden (imAccessDenied) when using a customer-scoped token, or a session without an IM-eligible role
  • 403 Forbidden (imNotEnabled) when Incident Management is not enabled for the organization
  • 403 Forbidden (imChannelWriteDenied) when you may not write the channel's scope (or the target scope of a move)
  • 400 Bad Request (invalidRequestBody) when :id is not a positive integer, type, name or config is missing or invalid, webhookUrl or email fails validation, config exceeds 8 KB, teamId is not a team of your organization, isActive is not a boolean (update), or the update body is empty or contains unsupported keys
  • 400 Bad Request (webhookHostHeaderForbidden) when config.headers sets the Host header
  • 404 Not Found (imChannelNotFound) when the channel does not exist, or belongs to another organization
  • 409 Conflict (imChannelReferencesExist) when deleting the organization's fallback channel. data.fallbackOrganizationIds lists the referencing organization
  • 409 Conflict (imChannelIsOrgFallback) when deactivating the organization's fallback channel

On this page