Slack
The Slack provider posts a message to a channel via chat.postMessage whenever a
deployment reaches a terminal state. The bot token is per organization — you install
the GantryCD Slack App into your own workspace and give GantryCD that workspace’s token.
1. Install the GantryCD Slack App
Install the GantryCD Slack App into your Slack workspace and grant it the
chat:write scope (plus chat:write.public if you want it to post to public channels it
hasn’t been invited to). After installation, copy the Bot User OAuth Token — it starts
with xoxb-. If the app only posts to channels it has been invited to, invite it to your
target channel(s).
v1 uses a pasted bot token. A future “Add to Slack” OAuth install flow can be added behind the same provider interface without changing how integrations are stored.
2. Create the integration
In the web app, go to Settings → Notifications → Add Integration: give it a name, pick the events, set the default channel (and optional channel-label key), add an optional stack-label selector, and paste the bot token. You can edit, disable, Test, and delete integrations from the same page, and see recent deliveries (including failures and dead-letters) below the list.
Equivalently, via the API — POST /api/v1/orgs/{org_id}/notification-integrations (requires
(notification_integration, create)):
{
"name": "slack-prod-deploys",
"provider_type": "slack",
"enabled": true,
"events": ["deployment_succeeded", "deployment_failed", "deployment_cancelled"],
"stack_label_selector": { "environment": "prod" },
"provider_config": {
"default_channel": "#deploys",
"channel_label_key": "slack-channel"
},
"auth_config": { "bot_token": "xoxb-..." }
}
events— which events to announce; see the event list.stack_label_selector— only notify for stacks whose labels are a superset of this map. Omit or leave empty to notify for every stack.changes_only— whentrue, skip deployments whose plan reported no changes. A plan that could not be measured is still sent.provider_config.default_channel— the channel used unless a stack overrides it.provider_config.channel_label_key— optional: the stack label whose value picks the channel for that stack. With"channel_label_key": "slack-channel", a stack labelledslack-channel=#team-aposts to#team-a; stacks without that label fall back todefault_channel.auth_config.bot_token— yourxoxb-token. Stored encrypted at rest and never returned by the API. On update, omitauth_configto keep the stored token.
3. Verify
Fastest check: POST /api/v1/orgs/{org_id}/notification-integrations/{integration_id}/test
sends a synthetic message through the provider immediately, so you can confirm the token and
channel without waiting for a deployment.
End to end: trigger a deployment on a matching stack and let it finish (or fail). The configured
channel receives a two-line message with a coloured stripe down its left edge — green for success,
red for failure, amber when the deployment is waiting on you. The first line names the stack and
what happened (the stack name links back to the deployment); the second gives the plan-change
counts, when they are available. Commit, author and PR sit in the small grey line underneath.
Only a deployment waiting on your confirmation carries a button, so it stands out in the channel.
The layout is documented in
Notifications internals.
Failures and dead-lettered messages are listed at
GET /api/v1/orgs/{org_id}/notification-deliveries; a successful delivery leaves no row there, so
the message itself is the only per-notification record — a delivered send is counted only in
aggregate, by gantrycd_notification_deliveries{outcome="sent"}.
To test delivery and retries without a real workspace, point SLACK_API_BASE_URL at a local
stub: a 200 {"ok":true} response marks the delivery sent; a 500 (or 200 {"ok":false})
drives the retry/dead-letter path.
Internals
Provider interface, message rendering, the delivery outbox, and retry/dead-letter behaviour are documented in Notifications internals.