Skip to main content

Prerequisites

Setup

1

Add the Slack integration in Courier

Go to the and select Slack. Click “Install”.

Courier Slack Integration

2

Create and configure a Slack app

  1. Go to the Slack Apps page and click “Create an App”.
  2. Choose “From scratch”, name your app, and select your development workspace.
  3. Under “OAuth & Permissions”, add these Bot Token Scopes: chat:write, im:write, users:read, users:read.email.
  4. Click “Install App to Workspace” and authorize.
  5. Copy the Bot User OAuth Access Token (starts with xoxb-).
The OAuth and Permissions page in Slack with the bot token scopes added

Slack OAuth Scopes

3

Design a Slack notification template

Go to the Courier and click + New > Message Template. Select Slack from your integrations. In the sidebar, click the new Slack block to open the Slack template editor. Add your message content.
4

Send a test message

Click Preview, then Create Test Event. Enter your bot token in the Access Token field. Click Send. Your message appears in Slack.

Profile requirements

Slack addresses the recipient by channel, user id, or email, so the profile you send to needs a slack object holding an access_token and one target. Store both once with , which merges into the profile and creates it if it does not exist:
The channel id, not its name. access_token is the bot token from your Slack app. It sits on the profile beside the target.
Order of precedence. Set more than one of channel, user_id, or email and Courier uses them in that order.
Then send to user_id and Courier resolves the address. For a one-off with no stored profile, pass it inline instead: "to": { "slack": { "access_token": "xoxb-xxxxx", "channel": "CL2MR6HEX" } }.

Send by user id

The call in every language, and the rest of the profile object.

Send to a recipient

Courier reads slack off the saved profile, so preferences apply and the value can change without touching this code.

Overrides

covers the two levels and which one wins. You can override the payload sent to Slack’s chat.postMessage using providers.slack.override.body. This is useful for advanced formatting, interactivity, and threading.

Slack blocks (Block Kit)

Send rich, interactive layouts using Slack blocks:
Design and preview your blocks visually with the Slack Block Kit Builder.

Replying in a thread

To reply to a thread, set the thread_ts value:

Mentioning users

Mention a user in your message using <@USER_ID> syntax in your template:
You can also use variables for dynamic mentions.

Preventing unwanted mentions

Slack automatically parses text for @name patterns and turns them into mentions. If your message content includes text that resembles a mention but shouldn’t trigger one, set verbatim: true on the Block Kit text object to disable this parsing. Courier’s standard template blocks (text, quote, etc.) don’t expose the verbatim flag. To use it, either pass raw Block Kit JSON via providers.slack.override.body.blocks or use a in Design Studio:

Slash command responses

If responding to a Slash Command, use the response_url as an incoming webhook:
Set override.slack.body.response_type to in_channel or ephemeral as needed.

Incoming webhooks

You can send messages to a channel using a Slack Incoming Webhook:

Updating notifications

To update a previously sent Slack message, set a “replacement key” (usually ts) in your notification template’s Slack channel settings. Courier will use this key to update the message instead of posting a new one.

Delivery tracking

When Courier sends a Slack message via Bot OAuth (chat.postMessage), it captures Slack’s ts (message timestamp identifier) and channel (conversation ID) from the API response. You can use these values to thread replies, update messages, or link back to the original Slack message.

Where delivery data appears

Slack-specific fields are returned in the providers array of the response and in webhook events:
Slack messages are marked as DELIVERED immediately after sending because Slack’s API confirms delivery synchronously. The delivered and sent timestamps will be very close together.
Incoming Webhook sends may not include reference data because Slack’s Incoming Webhook API does not return ts or channel in its response.

Troubleshooting

  • Missing or incorrect Slack scopes:
    • Double-check your app has all required scopes (chat:write, im:write, users:read, users:read.email, and chat:write.public for channels).
    • Reinstall your Slack app after updating scopes.
  • Bot not invited to channel:
    • Make sure your Slack app/bot is a member of the channel you want to message.
  • Invalid or missing tokens:
    • Ensure you are using the correct Bot User OAuth Access Token (starts with xoxb-).
    • Never use a user token or an expired token.
  • Permission errors or message not delivered:
    • Check the for error details and troubleshooting tips.
  • User or channel not found:
    • Double-check the email, user_id, or channel ID. For channels, copy the ID from the Slack URL.
  • Message Truncated:
    • Slack blocks limit the characters in a single section to 3k characters. Courier automatically truncates Slack messages over 3k characters by removing escape and formating characters that are added by Slack after submitting the block.
If you’re still stuck, reach out to Courier support at support@courier.com.

Provider details

Courier recommends routing to the channel. Naming this key in routing.channels instead is supported, and sends through just this provider.

Send to a specific provider

When that is worth doing, and what you give up: failover, channel priority, and providers you add later.