Discord Integration
Send messages from your VM to a Discord channel
The Discord integration lets your VM post messages to a Discord channel with
a plain HTTP request — no webhook URL on the VM, no Discord library required.
It's handy for build notifications, long-running job completions, or anything
an agent wants to tell you about.
If you want a bot that can *act* on Discord — read message history, react,
manage roles, call the full Discord Bot API — see the
[Discord Bot Integration](integrations-discord-bot) instead.
## Setup
Click the **Discord** tile on the [Integrations page](/integrations), or run:
```
exe.dev ▶ integrations setup discord
```
Either way, you'll be sent to Discord to authorize the exe.dev app. Discord
shows a server and channel picker: choose where the integration should post,
then click **Authorize**. That's the whole dance — Discord hands exe.dev an
incoming webhook for that channel, exe.dev stores it server-side, and the
integration is created for you.
Each integration posts to exactly one channel. To post to a second channel,
run setup again and pick a different channel.
## Sending messages
Attach the integration to a VM, then POST JSON to the integration hostname:
```
exe.dev ▶ integrations attach discord-hook vm:my-vm
Attached discord-hook to vm:my-vm
exe.dev ▶ ssh my-vm curl --json '{"content":"build finished ✅"}' https://discord-hook.int.exe.xyz/
```
The request body is Discord's [webhook execute
payload](https://discord.com/developers/docs/resources/webhook#execute-webhook),
so `content`, `embeds`, `components`, and friends all work:
```
curl --json '{"embeds":[{"title":"deploy done","description":"v42 is live 🚀","color":5763719}]}' \
https://discord-hook.int.exe.xyz/
```
Two query parameters pass through: `wait=true` to get the created message
back in the response, and `thread_id=<id>` to post into a thread.
## Notes
- The webhook URL is a secret, and it never touches your VM. exe.dev holds it
server-side and injects it when proxying your request.
- Messages are rate limited to 5 per minute per user, and exe.dev also
honors Discord's own per-webhook rate limit headers proactively — when a
limit is hit you get a 429 with a `Retry-After` header.
- The payload must be JSON (`Content-Type: application/json`), at most
256 KiB. File uploads (multipart) are not supported.
- The `username` and `avatar_url` override fields are rejected, and mass
mentions (`@everyone`, role and user pings) are neutralized — a VM can't
impersonate someone else or ping your whole server.
- If the webhook is deleted on the Discord side (Server Settings →
Integrations → Webhooks), requests return 404 — re-run
`integrations setup discord`.
## Manual webhook
Already have a Discord webhook URL? Create one in Discord under
**Server Settings → Integrations → Webhooks → New Webhook**, pick the
channel, **Copy Webhook URL**, then skip OAuth and add it directly:
```
exe.dev ▶ integrations add discord --name my-discord --webhook-url https://discord.com/api/webhooks/1234567890/XXXX
```