Skip to main content

Slack

Send notifications directly to Slack channels and direct messages. Zyphr integrates with Slack via OAuth, so your team connects their workspace through the Dashboard and you send messages via the API.

Features

  • OAuth Connection - Secure workspace connection via Slack's OAuth 2.0 flow
  • Channel Targeting - Send to any public or private channel the bot is invited to
  • Block Kit Support - Rich message formatting with Slack's Block Kit
  • Thread Replies - Reply to existing message threads
  • Delivery Tracking - Full message lifecycle with status updates
  • Dashboard Management - Connect, monitor, and manage from the Zyphr Dashboard

Quick Start

1. Connect Your Slack Workspace

Via Dashboard

  1. Navigate to Integrations in the sidebar
  2. Click Connect Slack
  3. You'll be redirected to Slack's OAuth consent screen
  4. Authorize Zyphr to access your workspace
  5. You'll be redirected back to the Dashboard with a confirmation

Via API

# Get the OAuth authorization URL
curl https://api.zyphr.dev/v1/slack/authorize \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
// Redirect your user to the authorization URL
const { url } = await zyphr.slack.getAuthorizeUrl();
window.location.href = url;

The OAuth callback is handled automatically at /v1/slack/callback.

2. Send a Message

curl -X POST https://api.zyphr.dev/v1/slack/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"channel_id": "C0123456789",
"text": "Hello from Zyphr!"
}'
await zyphr.slack.send({
connectionId: 'conn_abc123',
channelId: 'C0123456789',
text: 'Hello from Zyphr!',
});

3. Check Connection Status

curl https://api.zyphr.dev/v1/slack/status \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Sending Messages

Basic Text Message

curl -X POST https://api.zyphr.dev/v1/slack/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"channel_id": "C0123456789",
"text": "New deployment completed successfully."
}'

Message Parameters

ParameterTypeRequiredDescription
connection_idstringYesThe Slack connection to send through
channel_idstringYesSlack channel ID (e.g., C0123456789)
textstringYesMessage text (supports Slack markdown)
blocksarrayNoSlack Block Kit blocks for rich formatting
thread_tsstringNoThread timestamp to reply in a thread
unfurl_linksbooleanNoEnable link previews (default: true)
unfurl_mediabooleanNoEnable media previews (default: true)

Rich Messages with Block Kit

Use Slack's Block Kit for rich, interactive messages:

curl -X POST https://api.zyphr.dev/v1/slack/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"channel_id": "C0123456789",
"text": "Deployment notification",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "Deployment Complete" }
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Environment:*\nProduction" },
{ "type": "mrkdwn", "text": "*Status:*\n:white_check_mark: Success" },
{ "type": "mrkdwn", "text": "*Version:*\nv2.4.1" },
{ "type": "mrkdwn", "text": "*Duration:*\n3m 42s" }
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "View Logs" },
"url": "https://yourapp.com/deployments/123"
}
]
}
]
}'
await zyphr.slack.send({
connectionId: 'conn_abc123',
channelId: 'C0123456789',
text: 'Deployment notification',
blocks: [
{
type: 'header',
text: { type: 'plain_text', text: 'Deployment Complete' },
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: '*Environment:*\nProduction' },
{ type: 'mrkdwn', text: '*Status:*\n:white_check_mark: Success' },
],
},
],
});
tip

Always include a text field even when using blocks. The text field is used as the notification preview and fallback for clients that don't support Block Kit.

Thread Replies

Reply to an existing message thread by providing the thread_ts:

curl -X POST https://api.zyphr.dev/v1/slack/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"channel_id": "C0123456789",
"text": "Build logs attached.",
"thread_ts": "1234567890.123456"
}'

Managing Connections

List Connections

curl https://api.zyphr.dev/v1/slack/connections \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Connection Details

curl https://api.zyphr.dev/v1/slack/connections/CONN_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

List Available Channels

Retrieve the channels the Zyphr bot has access to in a connected workspace:

curl https://api.zyphr.dev/v1/slack/connections/CONN_ID/channels \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Disconnect a Workspace

curl -X DELETE https://api.zyphr.dev/v1/slack/connections/CONN_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
warning

Disconnecting a Slack workspace will prevent all future message delivery to that workspace. Pending messages will fail.

Message History

List Messages

curl "https://api.zyphr.dev/v1/slack/messages?connection_id=conn_abc123&status=sent&limit=25&offset=0" \
-H "X-API-Key: zy_live_your_api_key"

Query Parameters

ParameterTypeDescription
connection_idstringFilter by connection
channel_idstringFilter by channel
statusstringFilter by status: queued, sending, sent, delivered, failed
limitnumberResults per page (default: 25, max: 100)
offsetnumberPagination offset

Get Message Details

curl https://api.zyphr.dev/v1/slack/messages/MSG_ID \
-H "X-API-Key: zy_live_your_api_key"

Message Lifecycle

StatusDescription
queuedMessage accepted and queued for delivery
sendingMessage is being sent to Slack
sentMessage successfully delivered to Slack API
deliveredDelivery confirmed by Slack
failedDelivery failed (check error details)

Error Handling

Common error scenarios and how to handle them:

ErrorCauseResolution
channel_not_foundInvalid channel ID or bot not in channelVerify the channel ID and invite the Zyphr bot
not_authedOAuth token expired or revokedReconnect the Slack workspace
rate_limitedSlack API rate limit hitZyphr handles retries automatically
invalid_blocksMalformed Block Kit JSONValidate blocks with Slack's Block Kit Builder

Dashboard Management

From the Integrations page in the Dashboard:

  1. View connections - See all connected Slack workspaces with status
  2. Browse channels - View available channels per connection
  3. Monitor messages - Track delivery status and errors
  4. Manage connections - Connect new workspaces or disconnect existing ones

API Reference

MethodEndpointAuthDescription
GET/v1/slack/authorizeJWTGet OAuth URL
GET/v1/slack/statusJWTCheck Slack config status
GET/v1/slack/connectionsJWTList connections
GET/v1/slack/connections/:idJWTGet connection
DELETE/v1/slack/connections/:idJWTDisconnect workspace
GET/v1/slack/connections/:id/channelsJWTList channels
POST/v1/slack/sendAPI KeySend message
GET/v1/slack/messagesAPI KeyList messages
GET/v1/slack/messages/:idAPI KeyGet message

Rate Limits

Slack enforces strict API rate limits that Zyphr handles automatically. Understanding these limits helps you design reliable notification flows.

Limit TypeRateScope
Web API (per method)~1 request/secondPer workspace per method
Incoming Webhooks1 message/secondPer webhook URL
Burst allowanceShort bursts OKSlack allows brief spikes

How Zyphr Handles Rate Limits

  • Automatic retry: When Slack returns 429 Too Many Requests, Zyphr respects the Retry-After header and retries automatically
  • Queue-based delivery: Messages are sent via a queue, naturally spacing out delivery
  • No message loss: Rate-limited messages are retried, not dropped

Best Practices

  • Avoid sending to the same channel in tight loops — batch your updates or use a single rich message
  • Use threads for related updates — thread replies have separate rate limits from top-level messages
  • Monitor delivery status — if you see frequent rate_limited errors, reduce your send frequency
  • Use Block Kit for dense information — one rich message is better than five plain text messages
warning

If your application sends more than ~50 messages per minute to the same Slack workspace, expect throttling. Consider using digests or batching for high-volume notification scenarios.

Next Steps