The Platform API

Notification Channels

Manage your videos, ask questions, and build applications with the Platform API. Explore the operations below for request details, responses, and examples.

Notification Channels

Send alerts and job results to where your team already works — email, a webhook, WhatsApp, Telegram or Slack. Reads never return a channel secret in full; secret fields come back masked (for example ••••a1b2). Creating, changing or removing a channel needs a write role on the project.

GET/api/v1/notifications/capabilitiesList channel types available to your account

List channel types available to your account

The same catalogue as the project-level types endpoint, without needing a project — useful before your first project exists. Only types with available: true can deliver today; hide entries marked deprecated.

{
    "data": [
      { "type": "email", "label": "Email", "available": true, "deprecated": false, "secret_fields": [] },
      { "type": "webhook", "label": "Webhook", "available": true, "deprecated": false, "secret_fields": ["secret"] },
      { "type": "whatsapp", "label": "WhatsApp", "available": true, "deprecated": false, "secret_fields": [] },
      { "type": "telegram_official", "label": "Telegram (EndlessAI bot)", "available": true, "deprecated": false, "secret_fields": [] },
      { "type": "slack_app", "label": "Slack App", "available": true, "deprecated": false, "secret_fields": ["bot_token", "signing_secret"] }
    ],
    "capabilities": { "slack_official": true, "telegram_official": true }
  }

The list is abbreviated here.

GET/api/v1/projects/:projectId/notifications/typesList channel types for a project

List channel types for a project

Same shape as /notifications/capabilities, scoped to a project you can access.

GET/api/v1/projects/:projectId/notifications/channelsList channels

List channels

Returns every channel that delivers for this project, including personal channels shared across your projects. Secrets are masked.

{
    "data": [
      {
        "id": "CHANNEL_ID",
        "project_id": "PROJECT_ID",
        "type": "email",
        "name": "Night shift",
        "config": { "to": ["security@company.com"] },
        "min_severity": "medium",
        "events": ["alert.created", "alert.confirmed"],
        "broadcast_mode": "all",
        "enabled": true,
        "scope": "project",
        "created_at": "2026-10-01T09:12:00.000Z"
      }
    ]
  }
POST/api/v1/projects/:projectId/notifications/channelsCreate a channel

Create a channel

Request body:

{
    "type": "email",
    "name": "Night shift",
    "config": { "to": ["security@company.com"] },
    "min_severity": "medium",
    "events": ["alert.created", "alert.confirmed"],
    "broadcast_mode": "all",
    "connect_existing_alerts": true
  }

type (required) — a type from the types list. Email takes config.to (one or more addresses); webhook takes config.url (https) and an optional config.secret for signing — one is generated if you leave it out. WhatsApp, Telegram and Slack are connected from the app, where you link the chat itself.

min_severity — low (default), medium, high or critical

events — which events to send, for example alert.created, alert.confirmed, budget.threshold, digest.scheduled, job.result

broadcast_mode — all (every eligible alert, default) or routed (only alerts a rule sends to this channel by id)

connect_existing_alerts — also add the channel to every alert rule that already lists its channels

curl -X POST https://platform.endlessai.com/api/v1/projects/PROJECT_ID/notifications/channels \
    -H "X-Api-Key: YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "email",
      "name": "Night shift",
      "config": { "to": ["security@company.com"] },
      "min_severity": "medium"
    }'

Response (201):

{
    "data": { "id": "CHANNEL_ID", "type": "email", "name": "Night shift", "enabled": true },
    "connected_alert_rules": 2,
    "attached_jobs": 0
  }

Adding a destination that is already connected returns 400 — edit or re-enable the existing channel instead.

PATCH/api/v1/projects/:projectId/notifications/channels/:channelIdUpdate a channel

Update a channel

Send only the fields to change: name, config, min_severity, events, broadcast_mode, enabled. A masked secret sent back unchanged keeps the stored value. A personal channel can be changed only by the person who connected it.

{ "min_severity": "high", "enabled": true }
DELETE/api/v1/projects/:projectId/notifications/channels/:channelIdDelete a channel

Delete a channel

Also unlinks any chat bound to the channel.

{ "id": "CHANNEL_ID", "deleted": true }
GET/api/v1/projects/:projectId/notifications/channels/:channelId/bindingGet the linked chat

Get the linked chat

For a chat channel (WhatsApp, Telegram, Slack): whether a chat is linked, and which one.

{
    "data": {
      "configured": true,
      "connected": true,
      "platform": "telegram_official",
      "chat_title": "Warehouse team",
      "bound_at": "2026-10-02T08:30:00.000Z",
      "enabled": true
    }
  }
DELETE/api/v1/projects/:projectId/notifications/channels/:channelId/bindingUnlink the chat

Unlink the chat

Unlinks the chat but keeps the channel and its settings, ready to link again.

PUT/api/v1/projects/:projectId/notifications/channels/:channelId/project-settingsOverride a shared channel for this project

Override a shared channel for this project

A personal channel reaches several projects; its own settings are the defaults. Use this to change how it behaves for this project only. Set a field to null to go back to the default.

{
    "min_severity": "high",
    "events": ["alert.confirmed"],
    "scan_summaries": "short",
    "muted": false
  }

scan_summaries: full, short or off. muted: true stops this project's alerts reaching the channel.

DELETE/api/v1/projects/:projectId/notifications/channels/:channelId/project-settingsRemove this project's override

Remove this project's override

{ "data": { "cleared": true } }
GET/api/v1/projects/:projectId/notifications/channels/:channelId/project-overridesCount projects with their own override

Count projects with their own override

{ "data": { "count": 2 } }
POST/api/v1/projects/:projectId/notifications/channels/:channelId/apply-defaultsApply the channel defaults everywhere

Apply the channel defaults everywhere

Removes every project's override so the defaults apply.

{ "data": { "removed": 2 } }
GET/api/v1/projects/:projectId/notifications/deliveriesList recent deliveries

List recent deliveries

Newest first. Query param: limit (1-100, default 20). The examples show selected response fields.

{
    "data": [
      {
        "id": "DELIVERY_ID",
        "channel_id": "CHANNEL_ID",
        "alert_id": "ALERT_ID",
        "event": "alert.created",
        "status": "sent",
        "attempts": 1,
        "sent_at": "2026-10-03T22:14:05.000Z",
        "created_at": "2026-10-03T22:14:02.000Z"
      }
    ]
  }