Slack Incoming Webhook
Send messages to a Slack channel using Incoming Webhooks. No OAuth or bot setup required.
When to Use Send notifications to a specific channel CI/CD notifications, alerts, status updates Quick integration without full Slack app setup Prerequisites export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX
Get Webhook URL Create app: https://api.slack.com/apps → Create New App → From scratch Select Incoming Webhooks → Toggle On Click Add New Webhook to Workspace Select channel → Allow Copy Webhook URL
Important: When using $VAR in a command that pipes to another command, wrap the command containing $VAR in bash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.
bash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq .
Usage Simple Message
Write to /tmp/slack_request.json:
{ "text": "Hello, world." }
Then run:
bash -c 'curl -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @/tmp/slack_request.json'
With Formatting
Write to /tmp/slack_request.json:
{ "text": "Bold and italic text" }
Then run:
bash -c 'curl -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @/tmp/slack_request.json'
With Link
Write to /tmp/slack_request.json:
{ "text": "Check https://example.com|this link" }
Then run:
bash -c 'curl -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @/tmp/slack_request.json'
With Blocks (Rich Layout)
Write to /tmp/slack_request.json:
{ "text": "New review submitted", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "Danny left the following review:" } }, { "type": "section", "text": { "type": "mrkdwn", "text": "https://example.com|Overlook Hotel\n:star:\nDoors had too many axe holes." } } ] }
Then run:
bash -c 'curl -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @/tmp/slack_request.json'
With Fields
Write to /tmp/slack_request.json:
{ "text": "Deployment status", "blocks": [ { "type": "section", "fields": [ { "type": "mrkdwn", "text": "Environment:\nProduction" }, { "type": "mrkdwn", "text": "Status:\nSuccess" } ] } ] }
Then run:
bash -c 'curl -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @/tmp/slack_request.json'
Message Formatting
Syntax Result
bold bold
italic italic
~strike~ strike
code code
\n newline
Messages with ! may fail due to shell history expansion. Use heredoc:
bash -c 'curl -s -X POST $SLACK_WEBHOOK_URL -H "Content-type: application/json" -d @-' << 'EOF' {"text":"Deploy completed! :rocket:"} EOF
Response
Success: ok (HTTP 200)
Errors:
invalid_payload - Malformed JSON no_text - Missing text field no_service - Webhook disabled or invalid channel_not_found - Channel deleted channel_is_archived - Channel archived action_prohibited - Admin restriction Limitations One webhook = one channel only Cannot override username or icon (set in app config) Send only (no reading messages) Cannot delete messages after posting Rate limit: 1 message/second
For full API access, use the slack skill with Bot Token.
API Reference Webhooks Guide: https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks Block Kit Builder: https://app.slack.com/block-kit-builder Message Formatting: https://docs.slack.dev/messaging/formatting-message-text