Guidesclaude code slack notificationclaude code discord webhookclaude code slack integration

How to Send Claude Code Alerts to Slack or Discord

Wire Claude Code hooks to a Slack or Discord incoming webhook so your channel pings when an agent finishes or needs input — with the exact JSON, the shell gotcha that trips everyone, and where a chat webhook falls short.

Ian Brillantes · Founder & iOS EngineerJuly 12, 20265 min read

Quick answer

Create an incoming webhook in Slack or Discord, copy its URL, then attach a Claude Code Stop (and Notification) hook that POSTs a JSON message to it with curl. Slack expects {"text":"..."}; Discord expects {"content":"..."}. Use an absolute path to curl in the hook — hooks run in a non-interactive shell that won't load your PATH — and restart Claude Code so it picks up the new hook. That's the whole setup.

Slack and Discord webhooks are the fastest way to get Claude Code to announce itself — to a team channel, to a personal log, or just to a window you already keep open all day. The setup is a single hook, but there are two details (the payload key and a shell trap) that trip almost everyone. Here's the whole thing.

Step 1: Create the incoming webhook

Slack: create a Slack app for your workspace, enable Incoming Webhooks, and add a webhook for the channel you want to post to (say, #claude-code). Slack gives you a URL like https://hooks.slack.com/services/T000/B000/XXXX. Anyone who can post to that URL can post to that channel, so treat it like a secret.

Discord: open the target channel → Edit Channel → Integrations → Webhooks → New Webhook, then Copy Webhook URL. It looks like https://discord.com/api/webhooks/000/XXXX.

Heads up

A webhook URL is a credential. Anyone with it can post to your channel, so don't paste it into a public repo or a shared dotfile. If one leaks, delete the webhook and create a new one.

Step 2: Add the hook to settings.json

Attach the webhook to the Stop event so your channel pings when an agent finishes. The one difference between the two services is the JSON key — Slack uses text, Discord uses content.

Slack:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/bin/curl -s -X POST \"YOUR_SLACK_WEBHOOK_URL\" -H \"Content-Type: application/json\" -d '{\"text\":\"✅ Claude Code finished — your move.\"}'"
          }
        ]
      }
    ]
  }
}

Discord — same shape, but content instead of text:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/bin/curl -s -X POST \"YOUR_DISCORD_WEBHOOK_URL\" -H \"Content-Type: application/json\" -d '{\"content\":\"✅ Claude Code finished — your move.\"}'"
          }
        ]
      }
    ]
  }
}

Add a second entry under the Notification event with the same command (tweak the message to "needs your input") if you also want to hear about mid-task permission prompts, not just the finish. For why those are two separate events, see how to know when Claude Code is done.

Step 3: Restart Claude Code

Hooks are read when a session starts, so an edit to settings.json mid-session is ignored until you relaunch. Exit and restart Claude Code (then /resume if you want your conversation back). This step alone fixes a lot of "I added the hook and nothing posts" reports.

The one gotcha: absolute paths

If your curl posts fine when you run it by hand but the hook never reaches Slack, this is almost always why: hooks run in a non-interactive shell that doesn't load ~/.zshrc or ~/.bashrc. Any binary that's only on your PATH because of those files won't be found. Use an absolute path:

which curl
# → /usr/bin/curl   (paste the full path into your hook command)

This is the single most common cause of a hook that "works when I test it" but silently does nothing on its own. The full list of failure modes is in notifications not working.

Info

Want richer Slack messages? Both services accept structured payloads — Slack "blocks" and Discord "embeds" — so you can add fields, colors, and a title instead of a plain line. Start with plain text to confirm the plumbing works, then upgrade the JSON body once you see messages landing.

Where a chat webhook stops being enough

A Slack or Discord ping is perfect for a shared log or a desktop nudge. But be honest about what it isn't:

  • It's fire-and-forget text. The message says something happened; it can't update in place to show live status, and it can't tell you which of five parallel agents pinged unless you put that in the payload yourself.
  • You can't act from it. A permission prompt in Slack is just a notice — you still have to switch back to the terminal to approve it.
  • It lives on your desk. Great if Slack is always open on your Mac; less great when you've walked away and your phone is the only screen nearby.

Stop babysitting your terminal

Agentfy pushes Claude Code status to your iPhone — Live Activities, Dynamic Island, and instant alerts.

Download Agentfy

If what you actually want is away-from-desk monitoring — a push to your phone the instant an agent finishes, plus a glanceable Live Activity that shows the current state without opening anything — a dedicated monitor fits better than a chat channel. Agentfy installs the hooks for you via an open-source Claude Code plugin and shows each session as its own card. The two aren't mutually exclusive — plenty of people keep a #claude-code channel for the team log and run a phone monitor for themselves.

About the author

Ian Brillantes · Founder & iOS Engineer

Ian is the founder of Agentfy and a senior software engineer who lives in Claude Code daily. He builds the hooks-to-push-notification pipeline behind Agentfy and writes these guides from the same multi-agent workflow they describe.

Part of Running Claude Code Like a Pro

More guides in this series

Frequently asked questions

How do I send Claude Code notifications to Slack?+
Create an incoming webhook in your Slack workspace (via a Slack app with Incoming Webhooks enabled), copy the webhook URL, and add a Claude Code Stop hook that runs curl to POST a JSON body of the form {"text":"Claude Code finished"} to that URL. Restart Claude Code so the hook loads. When the agent finishes, Slack posts the message to the channel the webhook is bound to.
How do I send Claude Code notifications to Discord?+
In Discord, open a channel's settings → Integrations → Webhooks → New Webhook, copy the webhook URL, and add a Claude Code Stop hook that POSTs {"content":"Claude Code finished"} to it with curl. The payload key is content for Discord (Slack uses text), which is the single most common mistake when copying a Slack example.
My curl works in the terminal but the hook doesn't post to Slack. Why?+
Hooks run in a non-interactive shell that doesn't load your ~/.zshrc or ~/.bashrc, so a curl that's only on your PATH because of those files won't be found. Use an absolute path like /usr/bin/curl in the hook command. This resolves the large majority of works-manually-but-not-from-the-hook reports. Run 'which curl' to find the full path on your machine.
Can I get a Slack DM instead of a channel message?+
Incoming webhooks post to the specific channel they were created for, not to arbitrary users, so a plain webhook can't DM you. To reach yourself directly you'd use a Slack app with the appropriate scopes and the chat.postMessage API, or simply create the webhook for a private channel that only you are in. For most people a dedicated #claude-code channel is the simplest setup.
What are the limits of Slack or Discord alerts for Claude Code?+
A chat webhook is fire-and-forget text: it tells you something happened but it can't show a live, updating status, and you can't approve a permission prompt from the message. It's great for a team log or a desktop ping. If you want a persistent status you can glance at — or notifications on your phone with a Live Activity — a dedicated phone monitor fits better than a chat channel.

Ready to stop babysitting your terminal?

Agentfy pushes Claude Code status to your iPhone — Live Activities, Dynamic Island, and instant alerts. Set up in under a minute.

Download Agentfy