Connect FlutterFlow to Slack using an Incoming Webhook — create a webhook URL in Slack, then POST {"text": "your message"} from a FlutterFlow API Call with no auth header required. The webhook URL itself is the credential, making this the simplest app-to-Slack integration. For posting to multiple channels or using advanced Slack features, add a Bot token via a Firebase Cloud Function proxy.
| Fact | Value |
|---|---|
| Tool | Slack |
| Category | Communication |
| Method | FlutterFlow API Call |
| Difficulty | Beginner |
| Time required | 20 minutes |
| Last updated | July 2026 |
Sending Slack Notifications from Your FlutterFlow App
Slack is the communication hub for most tech-forward teams, and connecting your FlutterFlow app to Slack is one of the most immediately useful integrations you can build. Every time a new user signs up, an order is placed, a support ticket is submitted, or a metric crosses a threshold — your team can get an instant, actionable notification in Slack without having to open a dashboard. The Incoming Webhook makes this almost trivially easy: Slack gives you a unique URL, and any HTTP POST to that URL with a JSON body containing a text field instantly drops a message in the chosen channel.
Incoming Webhooks are free on all Slack plans, including the free tier. The free tier supports Slack apps and webhooks, making this one of the few integrations in this library that truly costs nothing to get started. The webhook URL is channel-specific — when you generate it, you select exactly which Slack channel it will post to, and it's locked to that channel. If you need to post to different channels based on event type, you'll need multiple webhooks or a Bot token approach.
For teams that need more: Slack's Web API (`chat.postMessage`) lets your app post to any channel, upload files, set message formatting with Block Kit, and more — but it requires a Bot token (`xoxb-`) which is a server secret. Putting a Bot token in a FlutterFlow API Call header would ship it inside the compiled app bundle. The correct upgrade path is a Firebase Cloud Function proxy: FlutterFlow calls the function, the function holds the `xoxb-` token and calls Slack's Web API. Both paths are covered in this guide, starting with the simple webhook.
Integration method
The simplest FlutterFlow-to-Slack path is a direct API Call to a Slack Incoming Webhook URL. The webhook is a unique URL that Slack generates when you add an app to a channel — POSTing a JSON body to it requires no Authorization header. For advanced use cases (posting to any channel, uploading files, or reading messages), you use Slack's Web API with a Bot token, which must be proxied through a Firebase Cloud Function. The Incoming Webhook handles the majority of FlutterFlow alert and notification use cases with zero backend setup.
Prerequisites
- A Slack workspace where you have permission to add apps (Workspace Owner or Admin, or permission settings that allow members to add apps)
- A FlutterFlow project (no Firebase required for the basic Incoming Webhook path)
- Clarity on which Slack channel should receive the messages
- For the advanced Bot token path: a Firebase project with Cloud Functions on the Blaze plan
Step-by-step guide
Create a Slack app, enable Incoming Webhooks, and copy the webhook URL
Go to api.slack.com/apps in your browser and click Create New App. Choose From scratch, give your app a name (e.g., 'FlutterFlow Notifier' — this is the name that appears as the message sender in Slack), and select your workspace from the dropdown. Click Create App. On the app configuration page, you'll land on the Basic Information page. Look at the left sidebar — click Incoming Webhooks. You'll see a toggle that says 'Activate Incoming Webhooks' with an Off state. Click the toggle to turn it On. The page will expand to show a Webhook URLs for Your Workspace section. Scroll to the bottom of that section and click Add New Webhook to Workspace. A Slack OAuth screen appears asking which channel this webhook should post to. Select the channel from the dropdown (e.g., #signups, #orders, or any channel you've created). Click Allow. Slack will redirect you back to the Incoming Webhooks settings page, and your new webhook URL will appear in the list — it looks like: https://hooks.slack.com/services/T.../B.../XXXXX. Click Copy next to the URL. This URL is your only credential for this integration. Treat it like a password — anyone who has this URL can post to your chosen Slack channel. Don't commit it to a public GitHub repository. However, it is safe to use directly in a FlutterFlow API Call in your private app, since the worst case of exposure is someone posting messages to your channel (not accessing your data). Test it quickly from your browser by pasting this into a tool like Hoppscotch: POST to the URL with body {"text": "Hello from FlutterFlow test"} and confirm the message appears in Slack.
Pro tip: If you need to post to multiple Slack channels (e.g., #orders AND #sales for the same event), create multiple webhooks — one per channel. You can add as many webhooks as you need to the same Slack app.
Expected result: You have a Slack Incoming Webhook URL (starting with https://hooks.slack.com/services/) copied. A test POST to the URL drops a 'Hello from FlutterFlow test' message in your chosen Slack channel.
Create a FlutterFlow API Call that posts to the Slack webhook
In FlutterFlow, click API Calls in the left navigation panel (the two-arrows icon). Click + Add → Create API Group. Name the group Slack_Webhooks. For the Base URL, enter https://hooks.slack.com. Leave the group-level Headers empty — Slack Incoming Webhooks don't require an Authorization header. Add a call inside the group: click + Add → Create API Call. Name it PostMessage. Set Method to POST. For the Endpoint, paste the path portion of your webhook URL — everything after hooks.slack.com. It will look like /services/T.../B.../XXXXX. Go to the Variables tab and add one variable: messageText (type: String). This will hold the dynamic message content your app generates. Click the Body tab. Set the body type to JSON. Enter: {"text": "{{ messageText }}"} This is all you need for a basic plain-text Slack message. Slack also supports Block Kit for richer formatting (buttons, sections, images), but for getting started, plain text is completely functional. Open the Response & Test tab. In the messageText test field, type a test notification like 'New order #1234 placed by Jane Smith for $89.99'. Click Test API Call. Slack returns 'ok' as the response body on success (a plain text string, not JSON). Check your Slack channel — the message should appear within a second or two. Save the API Group. Your Slack notification API Call is ready to use in action flows.
1{"text": "{{ messageText }}"}Pro tip: To format the Slack message with line breaks, use \n in the text string. For bold text, wrap words in *asterisks*. For example: "*New Signup* \n Name: John Doe \n Plan: Pro". Slack renders basic Markdown formatting inside message text.
Expected result: The FlutterFlow API Call test returns the string 'ok' and a test message appears in your Slack channel. The API Group is saved.
Bind the message text to dynamic app data
The real value of the Slack integration comes from including dynamic data — the actual user name, order number, or metric value — in the notification. In FlutterFlow, you compose the message text by combining static template strings with dynamic values from your app's state or database. Open the screen or component where the Slack notification should be triggered. Select the triggering widget (a button, a form, or an event listener) and open the Actions panel. Add the Slack PostMessage API Call action, then click into the messageText variable binding. FlutterFlow's variable binding panel lets you construct a string by mixing static text and dynamic values. Use the String Combination option (sometimes labeled 'Combine Text') to build a message like: 'New signup: ' + [currentUser.displayName] + ' (' + [currentUser.email] + ') on ' + [getCurrentTimestamp] Or, if you're notifying about a Firestore document, query the document first (using a Firestore Get Document action), then reference its fields in the message composition step. For complex message templates, it can be cleaner to store the final message string in an App State variable first (using a Set App State action that combines the fields), then pass that variable as messageText to the API Call. This keeps the action flow readable. Make sure the message text has meaningful context — at minimum, who, what, and when. A Slack message that just says 'New event occurred' is not useful. Aim for 'New order #[orderNumber] from [customerName] for [total] — [timestamp]'.
Pro tip: Keep Slack messages under 3,000 characters. For very long content (like full form submissions), post a summary in Slack and include a deep link to the record in your FlutterFlow app or your Firestore console rather than dumping the entire content into the message.
Expected result: The Slack message sent from the app contains real dynamic data from your app — user names, order IDs, record values — not placeholder text.
(Optional) Add a Bot token + Cloud Function for multi-channel or advanced Slack features
Incoming Webhooks are locked to one channel. If your app needs to post to different channels based on event type — or if you need Slack's Web API features like uploading files, listing channel history, or setting message metadata — you need a Bot token and a Cloud Function proxy. In your Slack app settings (api.slack.com/apps → your app), go to OAuth & Permissions in the left sidebar. Under Bot Token Scopes, click Add an OAuth Scope and add chat:write (required for chat.postMessage). Scroll up and click Install to Workspace → Allow. You'll receive a Bot User OAuth Token starting with xoxb-. This token is a secret — do NOT paste it into your FlutterFlow API Call. Instead, store it in Firebase Functions config: firebase functions:config:set slack.bot_token="xoxb-your-token-here" and deploy the Cloud Function shown in the code block. The function accepts a POST with channelId and text and calls Slack's chat.postMessage endpoint with the token in the Authorization header. In FlutterFlow, update your API Call to point at the Cloud Function URL instead of hooks.slack.com, and add channelId as a second variable. Now you can post to any channel dynamically by passing the target channel's Slack channel ID (found in the channel's URL or right-clicking the channel in Slack → Copy Link). For most FlutterFlow notification use cases, Incoming Webhooks are entirely sufficient. The Bot token path is worth the extra setup if you need dynamic channel selection, file uploads, or reading Slack data.
1// Firebase Cloud Function: Slack Bot token proxy2// npm install axios cors3// firebase functions:config:set slack.bot_token="xoxb-your-token"45const functions = require('firebase-functions');6const cors = require('cors')({ origin: true });7const axios = require('axios');89const SLACK_TOKEN = functions.config().slack.bot_token;1011exports.sendSlackMessage = functions.https.onRequest((req, res) => {12 cors(req, res, async () => {13 if (req.method !== 'POST') return res.status(405).send('Method Not Allowed');14 const { channelId, text } = req.body;15 if (!channelId || !text) {16 return res.status(400).json({ error: 'channelId and text are required' });17 }18 try {19 const response = await axios.post(20 'https://slack.com/api/chat.postMessage',21 { channel: channelId, text: text },22 {23 headers: {24 'Authorization': `Bearer ${SLACK_TOKEN}`,25 'Content-Type': 'application/json'26 }27 }28 );29 if (!response.data.ok) {30 return res.status(400).json({ error: response.data.error });31 }32 return res.status(200).json({ success: true, ts: response.data.ts });33 } catch (error) {34 return res.status(500).json({ error: error.message });35 }36 });37});Pro tip: Even with a Bot token, the Bot must be invited to the channel before it can post. In Slack, open the channel, click the channel name at the top → Integrations → Add an App → find your app and click Add. Or type /invite @YourBotName in the channel.
Expected result: The Cloud Function is deployed and the Slack Bot can post to any channel it's been invited to. FlutterFlow API Calls to the function route messages to the correct channel based on the channelId variable.
Common use cases
Startup app that posts new signups to a #signups Slack channel
A FlutterFlow SaaS app sends a Slack notification to #new-signups every time a user completes registration. The message includes the new user's name, email, and their selected plan. The founding team gets real-time signup visibility in Slack without building a separate analytics dashboard.
When a new user registers, send a Slack message to #new-signups with the user's name, email, and plan type. Format it clearly so the team can see key info at a glance.
Copy this prompt to try it in FlutterFlow
E-commerce app that alerts the team on high-value orders
A FlutterFlow marketplace app sends a Slack notification to #orders whenever an order exceeds a certain value. The message includes the order number, customer name, items purchased, and total amount. The operations team can prioritize fulfillment for high-value orders without checking the app dashboard constantly.
When an order is placed with a total above $500, send a Slack message to #orders with the order ID, customer name, item names, and total amount.
Copy this prompt to try it in FlutterFlow
Internal tool that reports daily activity summaries to Slack
A team-operations app built in FlutterFlow has an admin button that triggers a daily activity summary — total tasks completed, open issues, and team availability status — and posts it to the #daily-standup Slack channel. The report compiles from Firestore data and formats it as a structured Slack message with clear sections.
When the admin taps 'Send Daily Report', query today's activity from Firestore and post a formatted summary to the #daily-standup Slack channel.
Copy this prompt to try it in FlutterFlow
Troubleshooting
Slack returns 'no_text' error or the API Call fails with a 400 response
Cause: The JSON body is malformed — either the 'text' field is missing, the variable binding resolved to an empty string, or the JSON is not valid (missing quotes, stray characters).
Solution: In the FlutterFlow API Call test tab, manually type a hardcoded messageText value and test again. If that works, the issue is in the variable binding — check that the bound variable has a value before the API Call is triggered. Add a conditional action that only fires the Slack call when messageText is not empty.
The Incoming Webhook URL is posting to the wrong channel, or the channel changed
Cause: Incoming Webhook URLs are tied to a specific channel at creation time. If the channel was renamed, the webhook still works. But if you need to post to a different channel, the existing webhook URL won't work — you need a new one.
Solution: Go to api.slack.com/apps → your app → Incoming Webhooks → Add New Webhook to Workspace, select the correct channel, and copy the new URL. Update your FlutterFlow API Call endpoint with the new webhook path.
Bot token (xoxb-) was pasted into a FlutterFlow API Call header — security concern
Cause: Bot tokens are secrets. A token in an API Call header is compiled into the Flutter app binary and can be extracted with reverse-engineering tools. Anyone with your token can post to any Slack channel your Bot has access to.
Solution: Remove the token from the FlutterFlow API Call header immediately. In Slack, go to api.slack.com/apps → your app → OAuth & Permissions → Revoke Token and issue a new one. Store the new token only in Firebase Functions config and route calls through a Cloud Function proxy as shown in Step 4.
Slack message sends successfully in FlutterFlow test but doesn't appear in the channel
Cause: The webhook might point to an archived channel, or the app was removed from the workspace. Slack returns 'ok' even when delivery to an archived channel fails.
Solution: In the Slack app settings, go to Incoming Webhooks and check if the webhook's channel shows as archived. If so, create a new active channel in Slack and generate a new webhook for it. Also check that your Slack app hasn't been removed from the workspace under Manage Apps → Installed Apps.
Best practices
- Use Incoming Webhooks for simple, single-channel notifications — they require zero authentication overhead and are sufficient for the majority of FlutterFlow alert use cases.
- Keep the Incoming Webhook URL out of public source code repositories — while the risk is limited to channel spam rather than data breach, treat it like a credential.
- Only upgrade to a Bot token when you genuinely need multi-channel posting, file uploads, or Slack Web API features — the extra Cloud Function adds maintenance overhead.
- Never store a Slack Bot token (xoxb-) in a FlutterFlow API Call header — always proxy through a Firebase Cloud Function that holds the token in environment config.
- Make Slack messages actionable by including specific context (IDs, names, amounts, timestamps) rather than generic 'something happened' alerts — your team's time is valuable.
- For high-volume events (many notifications per minute), batch them server-side using a Cloud Function that aggregates events into a single summary message rather than flooding the channel.
- Test your webhook URL from a browser-based HTTP tool like Hoppscotch before setting up the FlutterFlow action flow — confirming the URL works independently makes debugging the action flow much easier.
Alternatives
Discord's channel webhook is functionally identical to Slack's Incoming Webhook — if your team is on Discord rather than Slack, the setup is nearly the same.
Microsoft Teams supports Incoming Webhooks with a similar zero-auth pattern if your organization uses Microsoft 365 instead of Slack.
Webex is the enterprise alternative if your team is in a Cisco-heavy or regulated environment where Slack is not approved.
Frequently asked questions
Is Slack's Incoming Webhook free to use?
Yes. Incoming Webhooks are included on all Slack plans, including the free tier. You can create multiple webhooks for different channels at no cost. The only potential cost is if your team upgrades Slack to a paid plan for features unrelated to the webhook integration (message history limits, larger file storage, etc.).
Can I send rich formatted messages (buttons, images, structured cards) with the Incoming Webhook?
Yes, through Slack Block Kit. Instead of sending a simple {"text": "..."} body, send a {"blocks": [...]} array with structured block objects for sections, dividers, images, and buttons. Block Kit Builder at app.slack.com/block-kit-builder lets you visually design a message and copy the JSON payload. Paste that JSON structure into your FlutterFlow API Call body, substituting dynamic values with FlutterFlow variables.
Can I receive Slack events (slash commands, button clicks, message events) in my FlutterFlow app?
Not directly. Slack sends interactive events (slash commands, block action button clicks, event subscriptions) to a registered HTTPS endpoint — your FlutterFlow app running on a user's device cannot serve as that endpoint. Route these events to a Firebase Cloud Function, which processes them and writes relevant data to Firestore. Your FlutterFlow app reads Firestore in real time. This gives you a workable two-way Slack integration without needing the app to have a server.
My Slack workspace has hundreds of members — can I send direct messages to individual members from FlutterFlow?
Yes, but it requires the Bot token path and a Cloud Function. With chat.postMessage and the Bot token, you can open a direct message channel with any workspace member by their Slack user ID and post to it. Get the user's Slack ID from Slack (their profile → hover → copy member ID) and store it in your app's user records. The Cloud Function accepts a userId parameter and opens the DM conversation. Direct messages are not possible via Incoming Webhooks — webhooks only post to channels.
Can I add the Slack integration without any backend at all?
Yes, for the Incoming Webhook path — it requires no Firebase, no Cloud Functions, and no server. You need only FlutterFlow and a Slack workspace. This makes the Slack Incoming Webhook one of the genuinely serverless integrations available to FlutterFlow builders. If you need anything beyond one-channel posting (multi-channel, Bot responses, reading data), a Cloud Function becomes necessary.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation