Discord webhooks let you send messages to channels without a bot. Post notifications, alerts, and rich embeds from your applications, CI/CD pipelines, or automation tools.
Key Takeaways
- 1Webhooks are unique URLs tied to a specific channel
- 2Send POST requests with JSON payload
- 3Support rich embeds with images, fields, and colors
- 4Create webhooks in Channel Settings → Integrations
- 5Keep webhook URLs secret—anyone with the URL can post
Webhook URL Structure
Discord webhook URLs contain two key pieces of information: the webhook ID and a secret token. Understanding this structure helps you manage webhooks and troubleshoot connection issues.
https://discord.com/api/webhooks/1234567890123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456The table below explains each component of the webhook URL so you can understand what each part represents.
| Component | Description |
|---|---|
1234567890... | Webhook ID |
abcdefgh... | Webhook token (secret) |
The token is the secret part of your webhook URL. Never share it publicly because anyone with this URL can post messages to your channel.
Creating a Webhook
Creating a Discord webhook takes just a few clicks in the channel settings. You can customize the webhook name and avatar to match your use case.
Open Channel Settings
Right-click the channel → Edit Channel
Go to Integrations
Click Integrations in the sidebar
Create Webhook
Click Webhooks → New Webhook
Copy URL
Click "Copy Webhook URL"
Once created, your webhook URL is ready to use immediately. You can customize the webhook name and avatar in the settings, or override them per-message in your payload.
Sending a Basic Message
The simplest Discord webhook message contains just a content field with your message text. This is all you need for basic notifications.
curl -X POST -H "Content-Type: application/json" \
-d '{"content": "Hello from my app!"}' \
"https://discord.com/api/webhooks/ID/TOKEN"async function sendDiscordMessage(webhookUrl, message) {
const response = await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: message })
});
if (!response.ok) {
throw new Error(`Discord webhook failed: ${response.status}`);
}
return response;
}
// Usage
await sendDiscordMessage(
'https://discord.com/api/webhooks/ID/TOKEN',
'Build completed successfully! 🎉'
);This function wraps the webhook call with proper error handling. The response is typically empty on success, so focus on checking the HTTP status code.
Rich Embeds
Discord embeds let you create visually rich messages with colors, fields, images, and timestamps. They are perfect for notifications that need to convey structured information at a glance.
const payload = {
username: 'Build Bot',
avatar_url: 'https://example.com/bot-avatar.png',
embeds: [{
title: 'Build #123 Succeeded',
description: 'All tests passed. Ready for deployment.',
url: 'https://ci.example.com/builds/123',
color: 0x00ff00, // Green (hex as integer)
fields: [
{ name: 'Branch', value: 'main', inline: true },
{ name: 'Commit', value: 'abc1234', inline: true },
{ name: 'Duration', value: '2m 34s', inline: true }
],
thumbnail: {
url: 'https://example.com/success-icon.png'
},
footer: {
text: 'CI Pipeline',
icon_url: 'https://example.com/ci-icon.png'
},
timestamp: new Date().toISOString()
}]
};
await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});This embed includes a title, description, colored sidebar, structured fields, and a timestamp. The color value is a decimal representation of the hex color, so green #00ff00 becomes 0x00ff00.
Payload Options
Discord webhooks support several payload fields that let you customize the message appearance and behavior. The table below shows all available options.
| Field | Type | Description |
|---|---|---|
content | string | Message text (up to 2000 chars) |
username | string | Override webhook name |
avatar_url | string | Override webhook avatar |
embeds | array | Up to 10 embed objects |
tts | boolean | Text-to-speech message |
files | multipart | File attachments |
The username and avatar_url fields let you override the webhook's default appearance per-message, useful when using one webhook for different types of notifications.
Common Use Cases
These examples show common patterns for integrating Discord webhooks into your development workflow. Each function can be called from your application when specific events occur.
Error Alert
async function sendErrorAlert(error, context) {
const payload = {
username: 'Error Monitor',
embeds: [{
title: '🚨 Error in Production',
description: `\`\`${error.message}\`\`\``,
color: 0xff0000, // Red
fields: [
{ name: 'Service', value: context.service, inline: true },
{ name: 'Environment', value: 'Production', inline: true }
],
timestamp: new Date().toISOString()
}]
};
await fetch(DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
}This error alert uses red coloring and includes the error message in a code block. Call it from your error handler to get immediate visibility into production issues.
New User Notification
async function notifyNewUser(user) {
const payload = {
embeds: [{
title: '👋 New User Signed Up',
color: 0x5865f2, // Discord blurple
fields: [
{ name: 'Email', value: user.email, inline: true },
{ name: 'Plan', value: user.plan, inline: true },
{ name: 'Source', value: user.referrer || 'Direct', inline: true }
],
timestamp: new Date().toISOString()
}]
};
await fetch(DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
}User signup notifications keep your team excited about growth. The Discord blurple color (0x5865f2) matches the platform's branding for a cohesive look.
Sending Files
Discord webhooks can also send file attachments. Use multipart form data instead of JSON to include files with your messages.
async function sendFileToDiscord(webhookUrl, file, message) {
const formData = new FormData();
formData.append('file', file);
formData.append('payload_json', JSON.stringify({
content: message
}));
const response = await fetch(webhookUrl, {
method: 'POST',
body: formData
});
return response;
}This function uses FormData to send a file alongside a message. The payload_json field contains any additional message data you want to include.
Security Best Practices
Webhook URLs are essentially passwords. Anyone who has your webhook URL can post messages to your Discord channel. Follow these practices to keep your webhooks secure.
Keep webhook URLs secret
Never commit webhook URLs to public repos. Anyone with the URL can post to your channel.
Use environment variables
Store URLs in DISCORD_WEBHOOK_URL environment variable.
Regenerate if compromised
Delete and recreate the webhook if the URL leaks.
With your webhook configured and secured, you are ready to integrate Discord notifications into your applications. The FAQ below addresses common questions about webhook behavior and limitations.
Try the URL Builder
Use our Discord Webhook template to explore webhook URL structure.