Setting Up a Slack Integration
Configure a Slack Incoming Webhook target and send structured messages from scripts, services, and CI/CD pipelines.
Use PayloadRelay to relay messages to Slack channels without managing Slack API tokens in each sending service. Configure a Slack target once and any system that can send HTTP requests can post to your Slack channel.
Purpose
This guide helps you:
- Create a Slack Incoming Webhook and add it as a PayloadRelay target.
- Send structured messages from scripts and services.
- Use Slack markdown formatting in relayed messages.
- Build a monitoring alert pipeline to Slack.
Prerequisites and permissions
- A Slack workspace where you can create Incoming Webhooks (or admin approval to do so).
- A PayloadRelay account with an active endpoint.
- The endpoint must accept
POSTwithJSONpayload format.
Step-by-step workflow
1. Create a Slack Incoming Webhook
- Go to api.slack.com/apps and create a new app (or use an existing one).
- Under
Incoming Webhooks, toggle the feature on. - Select
Add New Webhook to Workspace. - Choose the channel where messages should appear.
- Copy the webhook URL (e.g.
https://hooks.slack.com/services/T.../B.../xxxx).
2. Add the Slack target in PayloadRelay
- Open
Relay targetsand selectAdd target. - Choose
Slack webhook. - Paste the Slack Incoming Webhook URL.
- Give the target a descriptive name (e.g.
#ops-alerts Slack). - Save.
3. Attach the target to an endpoint
- Open the endpoint in
Endpoints. - In
Target destinations, add the Slack target. - Save.
Any payload sent to this endpoint will now be forwarded to your Slack channel.
4. Send a basic message
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
-H "Content-Type: application/json" \
-d '{
"alert": "Deployment complete",
"version": "2.4.0",
"environment": "production"
}'PayloadRelay delivers the payload fields as a formatted message in your Slack channel.
5. Slack markdown formatting
Slack supports a subset of markdown called mrkdwn. You can include formatting in your payload values:
| Format | Syntax | Example |
|---|---|---|
| Bold | *text* | *Deployment complete* |
| Italic | _text_ | _version 2.4.0_ |
| Strikethrough | ~text~ | ~deprecated~ |
| Code | `text` | `production` |
| Code block | ```text``` | Multi-line code |
| Link | <url|label> | <https://example.com|Dashboard> |
| User mention | <@USER_ID> | <@U012345> |
| Channel link | <#CHANNEL_ID> | <#C012345> |
Example with formatting:
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
-H "Content-Type: application/json" \
-d '{
"subject": "*Deployment Complete* :rocket:",
"details": "Version `2.4.0` deployed to _production_ by <@U012345>",
"link": "<https://example.com/status|View Status>"
}'6. Monitoring alert example
Send server monitoring alerts to Slack from a cron job or monitoring script:
#!/bin/bash
ENDPOINT="https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"
CPU=$(top -l 1 | grep "CPU usage" | awk '{print $3}' | tr -d '%')
MEM=$(vm_stat | awk '/Pages active/ {print $3}' | tr -d '.')
DISK=$(df -h / | awk 'NR==2 {print $5}')
HOSTNAME=$(hostname)
# Alert if disk usage exceeds 80%
DISK_PCT=${DISK%\%}
if [ "$DISK_PCT" -gt 80 ]; then
SEVERITY="critical"
EMOJI=":red_circle:"
else
SEVERITY="info"
EMOJI=":large_green_circle:"
fi
curl -s -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg subject "$EMOJI Server Health: $HOSTNAME" \
--arg severity "$SEVERITY" \
--arg cpu "$CPU%" \
--arg disk "$DISK" \
--arg host "$HOSTNAME" \
--arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{
subject: $subject,
severity: $severity,
cpu_usage: $cpu,
disk_usage: $disk,
hostname: $host,
timestamp: $time
}')"Schedule this script with cron to get periodic health updates in Slack:
# Run every 15 minutes
*/15 * * * * /path/to/health-check.sh7. Application error notification
Forward application errors to Slack from your backend:
import requests
import traceback
PAYLOADRELAY_URL = "https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"
def notify_error(error, context=None):
requests.post(PAYLOADRELAY_URL, json={
"subject": f"Application Error: {type(error).__name__}",
"error": str(error),
"traceback": traceback.format_exc(),
"context": context or {},
"severity": "error",
})
# Usage
try:
process_order(order_id)
except Exception as e:
notify_error(e, context={"order_id": order_id})
raiseExpected result and verification checks
- Messages appear in the configured Slack channel.
- Payload fields are visible and formatted in the Slack message.
- Requests appear in PayloadRelay
Request activitywith outcomeACCEPTED.
Common issues and fixes
- No message in Slack: verify the Slack Incoming Webhook URL is still valid and the app is installed in the workspace.
- Slack webhook returns
invalid_payload: confirm the payload is valid JSON and within size limits. - Formatting not rendering: use Slack's
mrkdwnsyntax, not standard Markdown. - Channel changed: update the Incoming Webhook URL if the channel was renamed or the webhook was regenerated.