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
type | Required config fields | Optional config fields |
|---|---|---|
webhook | webhookUrl | headers (object of header name to value) |
slack | webhookUrl | headers |
email | email |
webhookUrlmust be anhttporhttpsURL with a public hostname. Private, loopback and reserved IP addresses,localhost,*.local,*.internal,home.arpaand hostnames without a dot are rejected.headersmust not set theHostheader.configmay 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
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | webhook, slack or email. |
name | string | Yes | Display name, trimmed, max 120 characters. |
config | object | Yes | See channel types and config. |
teamId | integer | null | No | Team of your organization, or null/omitted for an org-wide channel. |
isActive | boolean | No | Default 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 asnullor"", 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 isnullor""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 anemailchannel towebhookrequires awebhookUrl. - Deactivating (
isActive: false) the organization's fallback channel is refused with409.
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 Unauthorizedwhen not authenticated403 Forbidden(imAccessDenied) when using a customer-scoped token, or a session without an IM-eligible role403 Forbidden(imNotEnabled) when Incident Management is not enabled for the organization403 Forbidden(imChannelWriteDenied) when you may not write the channel's scope (or the target scope of a move)400 Bad Request(invalidRequestBody) when:idis not a positive integer,type,nameorconfigis missing or invalid,webhookUrloremailfails validation,configexceeds 8 KB,teamIdis not a team of your organization,isActiveis not a boolean (update), or the update body is empty or contains unsupported keys400 Bad Request(webhookHostHeaderForbidden) whenconfig.headerssets theHostheader404 Not Found(imChannelNotFound) when the channel does not exist, or belongs to another organization409 Conflict(imChannelReferencesExist) when deleting the organization's fallback channel.data.fallbackOrganizationIdslists the referencing organization409 Conflict(imChannelIsOrgFallback) when deactivating the organization's fallback channel
Routing Rules
List, create, update and delete Incident Management routing rules: which team a new incident is assigned to, and an optional severity override.
Outbound Integrations
Forward Incident Management events to Slack, Microsoft Teams, Discord, Jira, PagerDuty, Opsgenie or a generic webhook, and inspect or retry deliveries.