← Back to documentation

Configure a Discord Integration

Send deployment notifications, alerts, and structured messages to Discord.

4 min read

Use PayloadRelay to send messages to Discord from a service that can make an HTTP request. Configure one Discord webhook target, and send a payload from an endpoint, a script, or an automation workflow.

Purpose#

Use this guide to:

  • Create a Discord webhook and add it as a PayloadRelay target.
  • Send a payload to a Discord channel.
  • Use the Discord formatting and embeds with a message template or a Discord payload.
  • Build a deployment notification workflow.

Before you start#

  • Make sure that you have the Manage Webhooks permission on a Discord server.
  • Create a PayloadRelay endpoint.
  • Configure the endpoint to accept POST with the JSON payload format.

Procedure#

1. Create a Discord webhook#

  1. In Discord, open the channel where the messages must appear.
  2. Select Edit Channel with the gear icon. Select Integrations, then Webhooks.
  3. Select New Webhook.
  4. Set the webhook name and avatar. They appear as the message sender.
  5. Copy the webhook URL, for example, https://discord.com/api/webhooks/1234/abcdef.

2. Add the Discord target in PayloadRelay#

  1. Open Relay targets and select Add target.
  2. Select Discord webhook.
  3. Paste the Discord webhook URL.
  4. Give the target a descriptive name, for example, #deployments Discord.
  5. Save.

3. Attach the target to an endpoint#

  1. Open the endpoint in Endpoints.
  2. In Outputs, add the Discord target.
  3. Save.

PayloadRelay sends a payload that goes to this endpoint to the Discord channel.

4. Send a basic message#

Code Example
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "Content-Type: application/json" \
  -d '{
    "event": "deploy",
    "version": "3.1.0",
    "environment": "production",
    "status": "success"
  }'

By default, PayloadRelay sends this JSON payload as the Discord message content. To send a selected message instead of the complete payload, configure a message template on the Discord destination. You can also send a Discord payload with fields such as content and embeds.

5. Discord markdown formatting#

Discord supports a large subset of Markdown in the message content. Use Markdown in a message template body or in a Discord content field:

FormatSyntaxExample
Bold**text****Deployment complete**
Italic*text**version 3.1.0*
Bold italic***text******critical alert***
Strikethrough~~text~~~~deprecated~~
Underline__text____important__
Inline code`text``production`
Code block```lang\ncode\n```Multi-line code
Block quote> text> Note: scheduled maintenance
Spoiler||text||||secret||

Example with formatting:

Code Example
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "Content-Type: application/json" \
  -d '{
    "content": "**Deployment Complete** 🚀\nVersion `3.1.0` deployed to *production*\n> All health checks passed\n> Zero-downtime migration applied"
  }'

6. Text-to-speech (TTS)#

A Discord webhook supports text-to-speech. When it is enabled, Discord speaks the message to the users in the channel. If the payload contains a top-level tts field, PayloadRelay sends that field:

Code Example
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Critical alert: database failover triggered",
    "tts": true
  }'

You can also enable TTS on the Discord destination in PayloadRelay. The destination value gives tts when the payload does not contain it. PayloadRelay keeps a top-level tts value in the payload. Use TTS for an urgent alert. Frequent TTS messages can be a problem for the channel members.

7. Deployment notification example#

A complete deployment notification workflow from an automation script:

Code Example
#!/bin/bash
set -euo pipefail

ENDPOINT="https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"
VERSION="${1:?Usage: deploy-notify.sh <version>}"
ENVIRONMENT="${2:-production}"
DEPLOYER="${3:-$(whoami)}"

notify() {
  local status="$1"
  local emoji="$2"
  local color="$3"

  curl -s -X POST "$ENDPOINT" \
    -H "Content-Type: application/json" \
    -d "$(jq -n \
      --arg content "$emoji Deployment $status: v$VERSION" \
      --arg version "$VERSION" \
      --arg env "$ENVIRONMENT" \
      --arg deployer "$DEPLOYER" \
      --arg status "$status" \
      --arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
      --argjson color "$color" \
      '{
        content: $content,
        embeds: [{
          title: "Deployment " + $status,
          color: $color,
          fields: [
            {name: "Version", value: $version, inline: true},
            {name: "Environment", value: $env, inline: true},
            {name: "Deployed by", value: $deployer, inline: true},
            {name: "Timestamp", value: $time, inline: false}
          ]
        }]
      }')"
}

# Before deployment
notify "started" "🔄" "3447003"

# Run your deployment
if ./deploy.sh "$VERSION" "$ENVIRONMENT"; then
  notify "succeeded" "" "3066993"
else
  notify "failed" "" "15158332"
  exit 1
fi

Usage:

Code Example
./deploy-notify.sh 3.1.0 production alice

8. Scheduled status report#

Send a daily status report to Discord from a cron job:

Code Example
#!/bin/bash
ENDPOINT="https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"

UPTIME=$(uptime -p 2>/dev/null || uptime | awk '{print $3,$4}')
LOAD=$(uptime | awk -F'load average:' '{print $2}' | xargs)
DISK=$(df -h / | awk 'NR==2 {printf "%s used of %s (%s)", $3, $2, $5}')

curl -s -X POST "$ENDPOINT" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg content "📊 Daily Status Report - $(hostname)" \
    --arg uptime "$UPTIME" \
    --arg load "$LOAD" \
    --arg disk "$DISK" \
    --arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    '{
      content: $content,
      embeds: [{
        title: "Daily Status Report",
        fields: [
          {name: "Uptime", value: $uptime, inline: false},
          {name: "Load average", value: $load, inline: false},
          {name: "Disk", value: $disk, inline: false},
          {name: "Timestamp", value: $time, inline: false}
        ]
      }]
    }')"

Expected result#

  • A message appears in the configured Discord channel.
  • A basic payload appears as the Discord message content.
  • A message template, and a Discord-native content or embeds payload, appear with the channel-native formatting.
  • A request appears in PayloadRelay Request activity as Completed (ACCEPTED).
  • The Markdown formatting is correct in Discord.

Common issues#

  • No message in Discord: make sure that the Discord webhook URL is active and not deleted.
  • PayloadRelay rejects the webhook URL: the URL must start with https://discord.com/api/webhooks/ or https://discordapp.com/api/webhooks/.
  • The formatting is wrong: use the Discord Markdown syntax, such as two asterisks for bold, in a message template body or a Discord content field. Do not use the Slack mrkdwn syntax.
  • A rate limit: Discord applies rate limits to a webhook. PayloadRelay retries a Discord delivery on a fast schedule, in the limit of the plan. Read PayloadRelay Request activity for the delivery failures.