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
- Navigate to Integrations in the sidebar
- Click Connect Slack
- You'll be redirected to Slack's OAuth consent screen
- Authorize Zyphr to access your workspace
- 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
| Parameter | Type | Required | Description |
|---|---|---|---|
connection_id | string | Yes | The Slack connection to send through |
channel_id | string | Yes | Slack channel ID (e.g., C0123456789) |
text | string | Yes | Message text (supports Slack markdown) |
blocks | array | No | Slack Block Kit blocks for rich formatting |
thread_ts | string | No | Thread timestamp to reply in a thread |
unfurl_links | boolean | No | Enable link previews (default: true) |
unfurl_media | boolean | No | Enable 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' },
],
},
],
});
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"
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
| Parameter | Type | Description |
|---|---|---|
connection_id | string | Filter by connection |
channel_id | string | Filter by channel |
status | string | Filter by status: queued, sending, sent, delivered, failed |
limit | number | Results per page (default: 25, max: 100) |
offset | number | Pagination 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
| Status | Description |
|---|---|
queued | Message accepted and queued for delivery |
sending | Message is being sent to Slack |
sent | Message successfully delivered to Slack API |
delivered | Delivery confirmed by Slack |
failed | Delivery failed (check error details) |
Error Handling
Common error scenarios and how to handle them:
| Error | Cause | Resolution |
|---|---|---|
channel_not_found | Invalid channel ID or bot not in channel | Verify the channel ID and invite the Zyphr bot |
not_authed | OAuth token expired or revoked | Reconnect the Slack workspace |
rate_limited | Slack API rate limit hit | Zyphr handles retries automatically |
invalid_blocks | Malformed Block Kit JSON | Validate blocks with Slack's Block Kit Builder |
Dashboard Management
From the Integrations page in the Dashboard:
- View connections - See all connected Slack workspaces with status
- Browse channels - View available channels per connection
- Monitor messages - Track delivery status and errors
- Manage connections - Connect new workspaces or disconnect existing ones
API Reference
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /v1/slack/authorize | JWT | Get OAuth URL |
GET | /v1/slack/status | JWT | Check Slack config status |
GET | /v1/slack/connections | JWT | List connections |
GET | /v1/slack/connections/:id | JWT | Get connection |
DELETE | /v1/slack/connections/:id | JWT | Disconnect workspace |
GET | /v1/slack/connections/:id/channels | JWT | List channels |
POST | /v1/slack/send | API Key | Send message |
GET | /v1/slack/messages | API Key | List messages |
GET | /v1/slack/messages/:id | API Key | Get message |
Rate Limits
Slack enforces strict API rate limits that Zyphr handles automatically. Understanding these limits helps you design reliable notification flows.
| Limit Type | Rate | Scope |
|---|---|---|
| Web API (per method) | ~1 request/second | Per workspace per method |
| Incoming Webhooks | 1 message/second | Per webhook URL |
| Burst allowance | Short bursts OK | Slack allows brief spikes |
How Zyphr Handles Rate Limits
- Automatic retry: When Slack returns
429 Too Many Requests, Zyphr respects theRetry-Afterheader 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_limitederrors, reduce your send frequency - Use Block Kit for dense information — one rich message is better than five plain text messages
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
- Discord Integration - Send messages to Discord servers
- Microsoft Teams - Send messages to Teams channels
- Notification Workflows - Include Slack in multi-channel workflows