Skip to content

Send Discord, Slack, Telegram, or Zalo alerts

Alert webhooks POST notifications to a Discord, Slack, Telegram, or Zalo URL when team events occur. A webhook channel is a team-scoped resource. Any owner can create, update, or delete it. Members cannot. You can disable a channel without deleting it.

Webhook channels are free to define. The number of non-deleted channels is plan-gated: Free 1, Starter 5, Standard 10. See plan limits.

TL;DR: Create a destination URL on Discord, Slack, Telegram, or Zalo, paste it into Alerting, pick events, and save. Discord and Slack use an incoming webhook URL. Telegram and Zalo use a sendMessage URL that includes chat_id. Treat every URL as a secret.

  • You must be an owner of the team.
  • Create a destination URL on Discord, Slack, Telegram, or Zalo using the platform sections below, then copy it.
  • Crystade rejects private, loopback, and link-local URLs. The URL must use the official prefix for the platform you select:
PlatformURL must start withExample shape
Discordhttps://discord.com/api/webhooks/https://discord.com/api/webhooks/<WEBHOOK_ID>/<WEBHOOK_TOKEN>
Slackhttps://hooks.slack.com/services/https://hooks.slack.com/services/<TEAM_ID>/<BOT_ID>/<TOKEN>
Telegramhttps://api.telegram.org/bothttps://api.telegram.org/bot<BOT_TOKEN>/sendMessage?chat_id=<CHAT_ID>
Zalohttps://bot-api.zaloplatforms.com/bothttps://bot-api.zaloplatforms.com/bot<BOT_TOKEN>/sendMessage?chat_id=<CHAT_ID>

Discord incoming webhooks post messages to one text channel. You need the Manage Webhooks permission on that server. See Discord’s Intro to Webhooks.

  1. Open the Discord server, then Server SettingsIntegrations.

  2. Choose Create Webhook (or WebhooksNew Webhook).

  3. Name the webhook, pick the text channel that should receive alerts, and save.

  4. Copy the Webhook URL. It looks like https://discord.com/api/webhooks/<WEBHOOK_ID>/<WEBHOOK_TOKEN>.

Slack incoming webhooks post messages to the channel chosen when you install the app. See Slack’s incoming webhooks guide.

  1. Create a Slack app in the workspace that should receive alerts. You can reuse an existing app.

  2. Open Incoming Webhooks and turn Activate Incoming Webhooks on.

  3. Choose Add New Webhook to Workspace, pick the channel, and authorize. To post into a private channel, you must already be a member of that channel.

  4. Copy the webhook URL under Webhook URLs for Your Workspace. It looks like https://hooks.slack.com/services/<TEAM_ID>/<BOT_ID>/<TOKEN>.

That URL is bound to the user who installed the app and to that channel. Slack searches for leaked webhook URLs and revokes them.

Telegram alerts use sendMessage. Crystade needs a bot token and the chat ID of the conversation that should receive messages. Encode both in the URL.

  1. Open Telegram and message @BotFather.

  2. Send /newbot and follow the prompts for a display name and a username.

  3. Copy the bot token BotFather returns. It looks like 123456789:AAExampleToken.

You must start a conversation with the bot before Telegram returns a chat ID.

  1. Open your bot in Telegram and tap Start, or send it any message.

  2. Request recent updates. In a browser or with curl, call:

    Terminal window
    curl "https://api.telegram.org/bot<BOT_TOKEN>/getUpdates"
  3. Read result[].message.chat.id. In a private chat this is your user ID.

A redacted getUpdates response looks like this. Use the value of chat.id as <CHAT_ID>:

{
"ok": true,
"result": [
{
"update_id": 123456789,
"message": {
"message_id": 1,
"from": {
"id": 100000000,
"is_bot": false,
"first_name": "Ada"
},
"chat": {
"id": 100000000,
"first_name": "Ada",
"type": "private"
},
"date": 1749632637,
"text": "hello"
}
}
]
}

Paste this into Crystade, with your token and chat ID:

https://api.telegram.org/bot<BOT_TOKEN>/sendMessage?chat_id=<CHAT_ID>

If getUpdates returns an empty result array, message the bot again and retry. Confirm you replaced <BOT_TOKEN> in the getUpdates URL.

Zalo alerts use sendMessage. Crystade needs a bot token and the chat ID of the person who messaged the bot. Encode both in the URL. Creating the bot follows Zalo’s create a bot flow.

  1. Open the Zalo app and search for the official account Zalo Bot Manager.

  2. In that chat, choose Create bot to open Zalo Bot Creator.

  3. Enter a bot name that starts with Bot (for example Bot Alerts) and the other required fields, then confirm.

  4. Copy the Bot Token Zalo sends to your account in a message.

Zalo does not show the chat ID in the creator UI. Capture it from an inbound message, either with Zalo getUpdates or with an HTTPS request inspector. getUpdates does not return messages while a webhook is configured; delete the webhook first if you use that API.

  1. Create a temporary HTTPS endpoint in a request inspector such as Hookdeck, and copy that URL.

  2. In Zalo Bot Creator, set the bot webhook URL to the inspector URL.

  3. Send any message to your bot from the Zalo account that should receive alerts.

  4. Open the captured JSON and copy message.chat.id (you can also use message.from.id in a private chat).

A redacted inbound payload looks like this. Use the value of message.chat.id as <CHAT_ID>:

{
"event_name": "message.text.received",
"message": {
"date": 1749632637199,
"chat": {
"chat_type": "PRIVATE",
"id": "<CHAT_ID>"
},
"message_id": "82599fa32f56d00e8941",
"from": {
"id": "<CHAT_ID>",
"is_bot": false,
"display_name": "Ada Lovelace"
},
"text": "hello"
}
}

Remove the inspector webhook from the bot after you have the chat ID. Crystade delivers outbound sendMessage calls; it does not need Zalo’s inbound webhook.

Paste this into Crystade, with your token and chat ID:

https://bot-api.zaloplatforms.com/bot<BOT_TOKEN>/sendMessage?chat_id=<CHAT_ID>

Open Alerting in the sidebar. Webhook deliveries live under Webhook Delivery.

Alerting page with Webhook Delivery empty state and Create Webhook

  1. Open Alerting for the team.

  2. Choose Create Webhook, name the channel, and pick Discord, Slack, Telegram, or Zalo.

    New Webhook form with name, URL, platform, and job and monitor event checkboxes

  3. Paste the destination URL from the matching platform section. Private, loopback, and link-local URLs are rejected.

  4. Select the events this channel should receive. An empty selection is allowed; the channel then delivers nothing until you add events.

  5. Save. The channel is enabled unless you disable it later.

EventWhen it fires
Cron job created, updated, or removedAn owner or member changes a cron job definition
job.execution.succeededA cron execution completed successfully and the previous run was not a failure
job.execution.failedA cron execution failed
job.execution.recoveredA cron execution succeeded after the previous run failed
Monitor created, updated, or removedA monitor definition changes
monitor.check.succeededA monitor check succeeded and the previous check was not a failure
monitor.check.failedA monitor check failed
monitor.check.recoveredA monitor check succeeded after a previous failure
Incident created or updatedA new incident is reported or an existing incident changes
Status page created, updated, or removedStatus page configuration changes
Status page subscriber added or removedSomeone subscribes or unsubscribes

Cron execution alerts include job identity, execution status, HTTP status when present, error details, start and end time, and attempt count. Monitor check alerts include monitor identity, location, success flag, and scheduled time.

Owners can disable a channel so it stays configured but stops delivering. Owners can also delete a channel, which counts against the non-deleted channel limit.

  • Send a test by triggering a subscribed event, for example a manual cron run that fails or succeeds.
  • Confirm Discord or Slack posts in the chosen channel, or that Telegram or Zalo delivers a message in the chat whose ID you used.
  • Disable the webhook and trigger again; no new message should appear.
SymptomWhat to check
Cannot create a channelOnly owners can create webhook channels. Check the plan channel limit.
URL rejectedUse the official prefix for the selected platform. Telegram and Zalo URLs must include /sendMessage?chat_id=. Private destinations are blocked.
Telegram or Zalo: no messagesMessage the bot at least once (Telegram: tap Start). Confirm <CHAT_ID> is the chat.id from an inbound payload, and that <BOT_TOKEN> is complete.
Zalo: URL accepted but silentConfirm the token is the Bot Token Zalo messaged you, not the inspector URL, and that chat_id is the user who messaged the bot.
No messagesConfirm the channel is enabled and subscribed to the event that fired.

Can I use Telegram or Zalo on a free plan?

Section titled “Can I use Telegram or Zalo on a free plan?”

Yes. Platforms are not plan-gated. The free plan allows 1 non-deleted webhook channel. Starter allows 5. Standard allows 10. See plan limits.

Why do Telegram and Zalo URLs need chat_id?

Section titled “Why do Telegram and Zalo URLs need chat_id?”

Discord and Slack bind the destination when you create the incoming webhook. Telegram sendMessage and Zalo sendMessage require chat_id on every call, so you put it in the query string.

The URL must use the official prefix for the platform you selected, and it must not point at a private, loopback, or link-local address. For Telegram and Zalo, include sendMessage and chat_id as shown in the platform sections.