Discord
Send notifications to Discord channels via webhook connections. Unlike Slack's OAuth flow, Discord uses incoming webhooks — you create a webhook in your Discord server and register it with Zyphr.
Features
- Webhook-Based Setup - No OAuth required, simple webhook URL configuration
- Rich Embeds - Send formatted messages with embeds, colors, and fields
- URL Validation - Verify webhook URLs before saving
- Test Messages - Send test messages to verify connectivity
- Delivery Tracking - Full message lifecycle with status updates
- Dashboard Management - Create, test, and manage connections from the Dashboard
Quick Start
1. Create a Discord Webhook
In your Discord server:
- Go to Server Settings > Integrations > Webhooks
- Click New Webhook
- Name the webhook (e.g., "Zyphr Notifications")
- Select the target channel
- Click Copy Webhook URL
2. Register the Connection
Via Dashboard
- Navigate to Integrations in the sidebar
- Click Connect Discord
- Paste your Discord webhook URL
- Give the connection a name
- Click Create
Via API
curl -X POST https://api.zyphr.dev/v1/discord/connections \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Alerts",
"webhook_url": "https://discord.com/api/webhooks/123456/abcdef"
}'
3. Send a Message
curl -X POST https://api.zyphr.dev/v1/discord/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"content": "Hello from Zyphr!"
}'
await zyphr.discord.send({
connectionId: 'conn_abc123',
content: 'Hello from Zyphr!',
});
Sending Messages
Basic Text Message
curl -X POST https://api.zyphr.dev/v1/discord/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"content": "New user signed up: jane@example.com"
}'
Message Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
connection_id | string | Yes | The Discord connection to send through |
content | string | Conditional | Message text (required if no embeds) |
embeds | array | No | Array of Discord embed objects |
username | string | No | Override the webhook's display name |
avatar_url | string | No | Override the webhook's avatar |
Rich Messages with Embeds
Discord embeds let you send formatted, card-style messages:
curl -X POST https://api.zyphr.dev/v1/discord/send \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "conn_abc123",
"embeds": [
{
"title": "Deployment Complete",
"description": "Production deployment finished successfully.",
"color": 3066993,
"fields": [
{ "name": "Environment", "value": "Production", "inline": true },
{ "name": "Version", "value": "v2.4.1", "inline": true },
{ "name": "Duration", "value": "3m 42s", "inline": true }
],
"footer": { "text": "Deployed by CI/CD" },
"timestamp": "2026-02-27T12:00:00.000Z"
}
]
}'
await zyphr.discord.send({
connectionId: 'conn_abc123',
embeds: [
{
title: 'Deployment Complete',
description: 'Production deployment finished successfully.',
color: 0x2ecc71, // Green
fields: [
{ name: 'Environment', value: 'Production', inline: true },
{ name: 'Version', value: 'v2.4.1', inline: true },
],
timestamp: new Date().toISOString(),
},
],
});
Embed Colors
Discord embed colors are decimal integers. Common values:
- Green (success):
3066993/0x2ecc71 - Red (error):
15158332/0xe74c3c - Blue (info):
3447003/0x3498db - Yellow (warning):
16776960/0xffff00
Multiple Embeds
You can include up to 10 embeds per message:
await zyphr.discord.send({
connectionId: 'conn_abc123',
content: 'Daily Report',
embeds: [
{ title: 'Email Stats', description: '1,234 sent, 98.5% delivered', color: 0x3498db },
{ title: 'Push Stats', description: '567 sent, 99.1% delivered', color: 0x2ecc71 },
],
});
Managing Connections
Validate a Webhook URL
Before creating a connection, verify the webhook URL is valid:
curl -X POST https://api.zyphr.dev/v1/discord/validate-webhook \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://discord.com/api/webhooks/123456/abcdef"
}'
List Connections
curl https://api.zyphr.dev/v1/discord/connections \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Update a Connection
curl -X PATCH https://api.zyphr.dev/v1/discord/connections/CONN_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Connection Name"
}'
Send a Test Message
Verify connectivity by sending a test message:
curl -X POST https://api.zyphr.dev/v1/discord/connections/CONN_ID/test \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Delete a Connection
curl -X DELETE https://api.zyphr.dev/v1/discord/connections/CONN_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
warning
Deleting a connection will prevent all future message delivery through that webhook. Pending messages will fail.
Message History
List Messages
curl "https://api.zyphr.dev/v1/discord/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 |
status | string | Filter by status: queued, sending, sent, failed |
limit | number | Results per page (default: 25, max: 100) |
offset | number | Pagination offset |
Get Message Details
curl https://api.zyphr.dev/v1/discord/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 Discord |
sent | Message successfully delivered to Discord |
failed | Delivery failed (check error details) |
Error Handling
| Error | Cause | Resolution |
|---|---|---|
invalid_webhook_url | Webhook URL format is incorrect | Verify the URL matches Discord's webhook format |
webhook_not_found | Webhook was deleted in Discord | Create a new webhook and update the connection |
rate_limited | Discord API rate limit hit | Zyphr handles retries automatically |
invalid_embeds | Malformed embed objects | Check embed structure against Discord's docs |
Dashboard Management
From the Integrations page in the Dashboard:
- Create connections - Add new Discord webhook connections
- Test connections - Send test messages to verify setup
- Monitor messages - Track delivery status and errors
- Manage connections - Update or remove connections
API Reference
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /v1/discord/connections | JWT | List connections |
POST | /v1/discord/connections | JWT | Create connection |
GET | /v1/discord/connections/:id | JWT | Get connection |
PATCH | /v1/discord/connections/:id | JWT | Update connection |
DELETE | /v1/discord/connections/:id | JWT | Delete connection |
POST | /v1/discord/connections/:id/test | JWT | Send test message |
POST | /v1/discord/validate-webhook | JWT | Validate webhook URL |
POST | /v1/discord/send | API Key | Send message |
GET | /v1/discord/messages | API Key | List messages |
GET | /v1/discord/messages/:id | API Key | Get message |
Rate Limits
Discord enforces rate limits on webhook requests. Zyphr handles these automatically.
| Limit Type | Rate | Scope |
|---|---|---|
| Per webhook | 5 requests/second | Per webhook URL |
| Per channel | 5 requests/second | Across all webhooks in a channel |
| Global | 50 requests/second | Per bot/application |
How Zyphr Handles Rate Limits
- Automatic retry: When Discord returns
429, Zyphr waits for theretry_afterduration and retries - Queue-based delivery: Messages are naturally spaced via the delivery queue
- No message loss: Rate-limited messages are retried, not dropped
Best Practices
- Use embeds to consolidate information — one embed with multiple fields is better than multiple messages
- Limit to 10 embeds per message — Discord's maximum
- Avoid rapid-fire sends to the same webhook — batch updates when possible
Next Steps
- Slack Integration - Send messages to Slack workspaces
- Microsoft Teams - Send messages to Teams channels
- Notification Workflows - Include Discord in multi-channel workflows