Channels

Create a notification channel

Creates a new notification channel for the authenticated project. Secrets (secret for webhooks, bot_token for Telegram, webhook_url for Discord/Slack/MS Teams/Google Chat, token+user_key for Pushover) are stored server-side but are never returned in any API response. Email channels are created unverified; a verification email is sent to the address and the channel will not alert until verified.

config must name only the fields its kind accepts, each exactly once, every URL must use https, and the branded kinds are pinned to their vendor's hosts — see ChannelCreate for the per-kind rules and the webhook escape hatch.

post/api/v1/channels

Request

  • Base URL: https://app.lastping.dev
  • URL: https://app.lastping.dev/api/v1/channels
  • Auth: API key in header X-Api-Key

Request body

kind'webhook' | 'telegram' | 'discord' | 'slack' | 'ntfy' | 'pushover' | 'msteams' | 'googlechat' | 'email' required

Channel type.

namestring required

Human-readable label for the channel.

configobject required

Kind-specific configuration object.

webhook — {"url": "https://…", "secret": "…"}. secret is WRITE-ONLY and never returned.

telegram — {"bot_token": "…", "chat_id": "…"}. bot_token is WRITE-ONLY and never returned.

discord — {"webhook_url": "https://discord.com/api/webhooks/…"}. webhook_url is WRITE-ONLY and never returned.

slack — {"webhook_url": "https://hooks.slack.com/services/…"}. webhook_url is WRITE-ONLY and never returned.

ntfy — {"topic_url": "https://ntfy.sh/my-topic"}. topic_url is not a credential and IS returned as target.

pushover — {"token": "…", "user_key": "…"}. Both token and user_key are WRITE-ONLY and never returned.

msteams — {"webhook_url": "https://…webhook.office.com/…"}. webhook_url is WRITE-ONLY and never returned.

googlechat — {"webhook_url": "https://chat.googleapis.com/v1/spaces/…"}. webhook_url is WRITE-ONLY and never returned.

email — {"address": "alerts@example.com"}. Channel is created unverified; a verification email is sent to the address.

Only the fields listed above for the kind are accepted, each exactly once; an unrecognised or repeated key is a 400 with code DESTINATION_CONFIG_INVALID. Every URL must use https, and the branded kinds are pinned to their vendor's hosts (slack → hooks.slack.com, discord → discord.com/discordapp.com, msteams → webhook.office.com/outlook.office.com/logic.azure.com/ logic.azure.us/environment.api.powerplatform.com, googlechat → chat.googleapis.com). Anything else belongs on kind webhook, which accepts any host.

Example request

{
  "kind": "webhook",
  "name": "Ops webhook",
  "config": {
    "url": "https://example.com/hook",
    "secret": "s3cr3t"
  }
}

Response

Channel created.

idstring uuid

Unique channel identifier.

kind'webhook' | 'telegram' | 'discord' | 'slack' | 'ntfy' | 'pushover' | 'msteams' | 'googlechat' | 'email'

Channel type.

namestring

Human-readable label.

targetstring

Non-secret hint about the channel destination.

  • webhook: the webhook URL.
  • telegram: "chat <chat_id>".
  • discord: the fixed string "discord webhook" (the actual URL is write-only).
  • slack: the fixed string "slack webhook" (the actual URL is write-only).
  • ntfy: the topic URL (not a credential, so it is returned in full).
  • pushover: the fixed string "pushover" (token and user_key are write-only).
  • msteams: the fixed string "teams webhook" (the actual URL is write-only).
  • googlechat: the fixed string "google chat webhook" (the actual URL is write-only).
  • email: the email address.
verifiedboolean

Whether the channel has been verified. Always true for webhook, telegram, discord, slack, ntfy, pushover, msteams, and googlechat channels (verified on creation). For email channels, false until the recipient clicks the verification link; unverified email channels do not send alerts.

disabledboolean

Whether the channel has been disabled (e.g. after repeated delivery failures).

disable_reasonstring

Human-readable reason the channel was disabled (omitted when not disabled).

created_atstring date-time

RFC 3339 UTC timestamp when the channel was created.

used_by_monitorsinteger

How many distinct monitors route any event to this destination. Counted across every event type, so a monitor routing both down and recovery here counts once. 0 means nothing would ever be sent to it.

Omitted when the server could not read the count. That happens on one path only: PATCH /api/v1/channels/{id} commits the update before it reads the count, so a read failure there leaves the destination saved and this field absent rather than reporting a 0 the destination has not earned. Re-read it from GET /api/v1/channels.

Example response

{
  "id": "c1d2e3f4-0000-0000-0000-000000000001",
  "kind": "webhook",
  "name": "Ops webhook",
  "target": "https://example.com/hook",
  "verified": true,
  "disable_reason": "too many delivery failures",
  "created_at": "2026-07-01T12:00:00Z",
  "used_by_monitors": 7
}

Changes

No recorded changes to this operation across all 2 revisions of this API.