# Send lead notifications to Slack > A channel hears about every new lead, with a button that opens it. Source: https://welcomeai.dev/docs/slack Category: Destinations Updated: 2026-09-08 --- Slack is the one destination that does not create a record. It posts a message: who arrived, what they left behind, and a button that opens the lead in WelcomeAI. Use it when somebody has to answer a lead in minutes rather than at the end of the day. It is per workspace. Each WelcomeAI workspace connects its own Slack app and picks its own channel, so two customers never see each other's leads. ## What you need A **Bot User OAuth Token**, which starts with `xoxb-`. It comes from a Slack app installed in your Slack workspace, and it takes about two minutes to make one: 1. Go to `api.slack.com/apps` and click **Create New App**, then **From scratch**. Name it whatever you want people to see when the notification arrives -- "WelcomeAI" is the obvious choice. 2. Pick the Slack workspace it belongs to. 3. Open **OAuth & Permissions** and add these **Bot Token Scopes**: - `chat:write` -- post the notification. - `chat:write.public` -- post to a public channel without being invited to it. - `channels:read` -- list your public channels, so you can pick one. - `groups:read` -- only if the notification goes to a private channel. 4. Scroll up and click **Install to Workspace**, then **Allow**. 5. Copy the **Bot User OAuth Token**. It is the one that starts with `xoxb-`. Not the User OAuth Token (`xoxp-`) and not the Signing Secret. A user token posts as you and stops working the day you leave the Slack workspace. ## Connect and route 1. In **Destinations**, connect Slack with the token. We call Slack to verify it before storing it, so a wrong paste fails here rather than on your first lead. 2. Create a route and pick the channel. Public channels are listed first; a private one is listed too, but only if you added `groups:read`. 3. Choose which widget's leads it takes. Leave it on all widgets and it takes every lead. See **One route per widget** below -- it is how two forms reach two different channels, and it decides which questions the mapper offers. 4. Map what the message should show. Slack has no fields of its own, so what you are mapping are the lines of the notification: **Name**, **Email**, **Phone**, **Company**, **Message**, **Page**, and an **Extra note** for the one question that matters to you and is not on that list. The left column holds the questions the chosen widget's form asks. ## One route per widget, and so one per form A route's scope is a widget. Leave it on all widgets and the route takes every lead; pin it to one and it takes only that widget's. That is also how two forms reach two places, because a widget runs one form: its lead capture names the form it asks, so choosing the widget chooses the form. A contact form on one widget and a demo request on another are two routes, each to its own destination. Two forms on the same widget is not a thing you can set up -- swap the widget's form and you have changed which form it asks. Choosing a widget does one more thing: the mapper's left column shows the questions **that** form asks, instead of every question every form in the workspace asks. So a route built for the demo request is not mapped against the contact form's fields, and the questions on screen are the ones a visitor will actually be asked. Leave the route on all widgets and you get all of them, which is right -- the route takes leads from all of them. One consequence worth knowing: a lead captured by the assistant in conversation carries the widget it came from, so a widget-scoped route takes it like any other. A lead pushed through the API with no widget is taken only by a route with no widget. ## What the message looks like A bold first line ("New lead"), the person's name under it, the lines you mapped as two columns, and a primary button, **Open the lead**, that goes straight to that lead in your workspace. Under it, a grey line with the workspace and the widget it came from. Empty lines are left out. A lead who did not give a phone number does not produce a "Phone" row that says nothing. ## More than one bot You can connect Slack as many times as you like. **Connect another** on the Slack card adds a second account, and each route picks which one it posts as. Two reasons to bother. One is two Slack workspaces -- an internal one and a client's. The other, more common, is two apps in the same workspace, so the notification arrives under the name that suits it: a "WelcomeAI Sales" app posting to #sales and a "WelcomeAI Support" app posting to #support. Slack shows the app's own name and icon on every message, so this is what makes a channel's notifications look like they belong to it. Connected accounts are named `Slack ยท (@)`, because two apps in one Slack workspace share the workspace name and only the handle tells them apart. You can rename a connection to anything you like when you connect it. ## Private channels `chat:write.public` covers public channels only. For a private channel, open it in Slack and run `/invite @` followed by your app's name. Until you do, Slack answers `not_in_channel` and nothing arrives -- and the channel picker says so next to the channel, before you choose it. ## Check it before a visitor does - **Check connection** re-asks Slack whether the token still works, and records the answer with today's date. - **Send sample lead** posts one invented lead down this route, so you can see exactly what lands in the channel. It is marked `[Sample]` in the message, it is not stored as a lead, and it does not count against your plan. ## Unlike a CRM Two rules are different here, on purpose: - **A lead with no email and no phone is still sent.** A CRM record with no way to reach the person is not worth creating; a channel still wants to know that somebody asked about pricing and left no address. - **Nothing is deduplicated.** The same person answering twice updates one HubSpot contact, and produces two Slack messages. They are two events, and a channel is a record of events. ## When it fails The dispatch log shows Slack's own answer. The three you will meet: - `not_in_channel` -- the app is not in that channel. Invite it, or pick a public one. - `channel_not_found` -- the channel was deleted, renamed into one this token cannot see, or is private and the token has no `groups:read`. - `invalid_auth` -- the token was revoked, or the app was removed from the Slack workspace. Reinstall the app and paste the new token. A failed message is retried five times over about two hours. A wrong scope is not retried: it would be just as wrong in five minutes, so the log says so immediately and the connection is flagged.