← Back to documentation

Setting Up a Discord Integration

Configure a Discord webhook target and send deployment notifications, alerts, and structured messages to Discord channels.

8 min read

Use PayloadRelay to send messages to Discord channels from any service that can make HTTP requests. Configure a Discord webhook target once and route payloads from endpoints, scripts, and CI/CD pipelines.

Purpose

This guide helps you:

  • Create a Discord webhook and add it as a PayloadRelay target.
  • Send payloads to Discord channels.
  • Use Discord formatting and embeds with message templates or Discord-native payloads.
  • Build a deployment notification pipeline.

Prerequisites and permissions

  • A Discord server where you have Manage Webhooks permission.
  • A PayloadRelay account with an active endpoint.
  • The endpoint must accept POST with JSON payload format.

Step-by-step workflow

1. Create a Discord webhook

  1. In Discord, open the channel where you want messages to appear.
  2. Select Edit Channel (gear icon) → IntegrationsWebhooks.
  3. Select New Webhook.
  4. Set the webhook name and avatar (these appear as the message sender).
  5. Copy the webhook URL (e.g. https://discord.com/api/webhooks/1234/abcdef).

2. Add the Discord target in PayloadRelay

  1. Open Relay targets and select Add target.
  2. Choose Discord webhook.
  3. Paste the Discord webhook URL.
  4. Give the target a descriptive name (e.g. #deployments Discord).
  5. Save.

3. Attach the target to an endpoint

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

Payloads sent to this endpoint will now be forwarded to your 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 Discord message content. To send a curated channel-native message instead of a full payload dump, configure a message template on the Discord output or send a Discord-native payload with fields such as content and embeds.

5. Discord markdown formatting

Discord supports a rich subset of Markdown in message content. Use Markdown in a message template body or in a Discord-native 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. TTS (Text-to-Speech) option

Discord webhooks support text-to-speech. When enabled, Discord reads the message aloud to users in the channel. PayloadRelay passes through a top-level tts field if included in your payload:

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 output in PayloadRelay. The output setting supplies tts when the payload does not include it; a top-level tts value in the payload is preserved. TTS is useful for urgent alerts, but use sparingly to avoid disrupting channel members.

7. Deployment notification example

A complete deployment notification pipeline from a CI/CD 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 and verification checks

  • Messages appear in the configured Discord channel.
  • Basic payloads appear as Discord message content.
  • Message templates or Discord-native content/embeds payloads appear with channel-native formatting.
  • Requests appear in PayloadRelay Request activity with outcome ACCEPTED.
  • Markdown formatting renders correctly in Discord.

Common issues and fixes

  • No message in Discord: verify the Discord webhook URL is still active and hasn't been deleted.
  • Webhook URL rejected: Discord webhook URLs must start with https://discord.com/api/webhooks/ or https://discordapp.com/api/webhooks/.
  • Formatting not rendering: use Discord Markdown syntax (double asterisks for bold, etc.) inside a message template body or Discord-native content field, not Slack mrkdwn.
  • Rate limits: Discord has its own rate limits on webhooks. PayloadRelay retries Discord deliveries automatically on a fast schedule capped by your plan; check PayloadRelay Request activity for delivery failures.

Related guides