Notification channels
Get pinged in Slack, Discord, or Telegram when inbound mail arrives, emails bounce, deliverability dips, or a webhook auto-disables. Channels are sibling to webhooks — same retry + auto-disable guarantees, but PostStack does the formatting so the message is human-readable rather than a JSON blob.
Supported platforms
Slack
Uses Incoming Webhooks. In your Slack workspace, add the "Incoming Webhooks" app, pick the channel you want to post in, and copy the webhook URL.
config.webhookUrl https://hooks.slack.com/services/T000/B000/abc123Discord
Uses Discord webhooks. In your server, open the target channel → Edit Channel → Integrations → Webhooks → New Webhook → Copy URL.
config.webhookUrl https://discord.com/api/webhooks/<id>/<token>Telegram
Uses the Telegram Bot API. Message @BotFather, run /newbot, and copy the token it gives you. Add the bot to the target chat or channel, send any message, then call https://api.telegram.org/bot<token>/getUpdates to find the chat id.
config.botToken 123456789:ABCdef-GhIJklm_NopQRsTuvWXyz
config.chatId -1001234567890Events
Each channel subscribes to one or more event types. Subscribe to as many or as few as you want; only the events in events trigger a post to the channel.
inbound_email.received— new mail arrived at a mailbox under one of your verified domainsemail.bounced— an outbound email hard- or soft-bouncedemail.complained— the recipient flagged your email as spamemail.suppressed— an address was added to your suppression listwebhook.disabled— one of your webhook endpoints auto-disabled after 20 consecutive failuresdomain.verification_failed— a domain failed re-verificationdeliverability.degraded— deliverability metrics dropped below a healthy threshold
Scope
Channels target one of three scopes:
- Team-wide (default, both
domainIdandmailboxIdnull) — fires for any matching event across the whole team. - Per-domain (
domainIdset) — fires only when the event relates to that domain. - Per-mailbox (
mailboxIdset) — fires only when inbound mail lands in that specific mailbox.
Multiple channels can match the same event — they all fire (stacking model, not most-specific-wins). Use this to route, e.g., your support@ mailbox to a customer- facing Slack channel and the team-wide email.bounced stream to an engineering Telegram chat at the same time.
API
/notification-channelsCreate a notification channel. The config shape varies per platform — pick one of slack | discord | telegram.
{
"type": "telegram",
"name": "Ops alerts",
"events": ["email.bounced", "webhook.disabled"],
"config": {
"botToken": "123456789:ABCdef-GhIJklm_NopQRsTuvWXyz",
"chatId": "-1001234567890"
}
}/notification-channelsList all notification channels for your team. Secrets in config are masked.
{
"channels": [
{
"publicId": "nc_abc...",
"type": "telegram",
"name": "Ops alerts",
"events": ["email.bounced"],
"active": true,
"configSummary": { "botToken": "•••••", "chatId": "-1001234567890" },
"consecutiveFailures": 0,
"disabledAt": null,
"lastUsedAt": "2026-05-27T09:32:11.000Z",
"createdAt": "2026-05-27T10:00:00.000Z"
}
]
}/notification-channels/:publicIdUpdate a channel's name, events, scope, or config. Omitted config fields are preserved (so you can rotate just the bot token without re-supplying the chat id). Set enabled:true to re-enable an auto-disabled channel.
{
"name": "Ops alerts (renamed)",
"events": ["email.bounced", "email.complained"],
"enabled": true
}/notification-channels/:publicId/testSend a canned test notification to the channel. Useful for verifying the integration works without waiting for a real event.
{ "success": true, "statusCode": 200, "responseBody": "ok" }/notification-channels/:publicIdDelete a channel. The full delivery history is removed (cascade).
{ "success": true }Retry & auto-disable
Failed deliveries retry with exponential backoff up to 8 attempts (30 s, 2 m, 10 m, 30 m, 2 h, 8 h, 16 h). Platform rate-limit 429 responses honour the platform's Retry-After hint instead of the default schedule. After 20 consecutive permanently-failed deliveries the channel auto-disables, the team owner gets an email, and an in-app notification appears in the dashboard bell. Re-enable from the dashboard or via PUT /notification-channels/:publicId with { "enabled": true } once the integration is healthy again.
Scopes
Two OAuth scopes guard the API: notifications:read for list/get/deliveries endpoints, notifications:manage for create/update/delete/test/replay. Granting notifications:manage implicitly grants :read.