Moving Slack apps, bots and webhooks to Mattermost

Slack exports leave integrations behind, so the rebuild is separate work. This page shows which webhook payloads port unchanged, which Slack fields and mentions do not, and how to inventory and re-create bots before cutover.

On this page

Migrate Slack integrations to Mattermost without losing the workflows behind them

Most Slack exits start with a renewal, a data residency requirement or a lock-in concern, and the workspace they leave behind is full of bots, slash commands and incoming webhooks that someone depends on every day. The key point to plan around is that message history moves through Mattermost's documented import path, while integrations do not. The Slack migration tooling converts users, channels, direct messages, threads and attachments, but apps, webhooks and custom emoji images stay behind. Every integration therefore becomes a separate rebuild with its own owner, test and cutover step. The work usually falls to the platform or IT team, working with the people who own each app or script. Start by inventorying every Slack app, slash command, outgoing and incoming webhook and scheduled job, and record who owns it, which channels it posts into and what systems it calls. Incoming webhooks are the cheapest to move. Mattermost accepts Slack-style payloads, including the payload= prefix when no Content-Type header is sent and the icon_emoji parameter from v5.14, and it translates <url|text> links and <!channel>, <!here> and <!all> mentions. Test each sender against a staging Mattermost server before changing its URL.

The risk sits in what does not translate. Mattermost's incoming webhooks do not support mrkdwn, parse or link_names, <!everyone> and <!group> mentions, <#CHANNEL_ID> channel links or single-asterisk *bold* formatting. Messages that depend on these will render incorrectly or silently lose their mentions, so search each payload template for them and rewrite the affected text. Slash commands and bots need a fresh Mattermost integration and a new endpoint, so they are a development task rather than a configuration change. Confirm with your own developers which Mattermost API features your bots need, and plan an overlap period where the Slack app and its Mattermost replacement both run in a test channel. For cutover, keep a written register of every integration with its owner, its replacement, its test result and its rollback path. Confirm the Mattermost version you will deploy against the current Mattermost server releases page, since support windows determine when you must upgrade again. The effort depends mostly on how many custom bots exist and how much of their output depends on Slack-specific formatting, so ask your implementation partner to size the inventory first and quote the rebuild from that written scope.

Which Slack integration pieces map to Mattermost and how clean each move is

This table compares each Slack integration piece with its Mattermost equivalent and rates the move as clean, needing rework, or a gap. Read it as an inventory checklist: anything marked clean can usually be reused as written, anything needing rework must be edited before cutover, and anything marked gap must be rebuilt or replaced by a different mechanism.

Slack capabilityMattermost equivalentMigration note
Incoming webhooksIncoming webhooks accepting Slack-style payloadsClean for basic payloads. Requests without a Content-Type header take the payload= prefix; test each sender after cutover.
Outgoing webhooksOutgoing webhooks configured per teamNeeds rework. Recreate each one, point it at the new URL and confirm the trigger words and callback settings in your own environment.
Slash commandsCustom slash commands on a teamNeeds rework. Recreate each command and its endpoint; the command name and response handling must be confirmed against your Slack inventory.
Bots and appsBot accounts and integrations built against the Mattermost APIGap for installed Slack apps. Slack app installations do not migrate, so each bot needs a rebuild or a replacement from its owner.
Mention and link formattingSlack-style <url|text> links and <!channel>, <!here>, <!all> mentionsNeeds rework. Remove mrkdwn, parse and link_names parameters, <!everyone>, <!group>, <#CHANNEL_ID> links and single-asterisk bold.
Custom emojiCustom emoji on the Mattermost serverGap for images. Slack custom emoji images do not move in the import, so re-upload each one the teams still use.
User groupsChannel membership and team membership settingsGap. User groups do not migrate, so rebuild group targeting by hand or through your own automation.
Slack Connect channelsNo direct equivalent in MattermostGap. Shared channels with outside organizations do not come across; plan a separate arrangement such as guest accounts with a security review.

What the Slack export carries and what you must rebuild by hand

A Slack export is the starting point for moving people and history, but it does not carry the apps, webhooks and bots that teams depend on. The cards below cover what the export plan allows, how the Mattermost import path works, what falls out during conversion, and how to inventory the integrations you must recreate before cutover.

Export plan sets the scope

Every Slack plan can export public channels, but private channels and direct messages need a Business+ or Enterprise plan. Custom exports by member or conversation are limited to Enterprise. Confirm which plan your workspace is on before you plan the cutover, because a Free or Pro export will be missing private conversations that your teams may expect to see in Mattermost. Request the export early so the approval step does not hold up the project.

mmetl converts, mmctl loads

Mattermost moves a Slack export in two steps. The mmetl tool converts the Slack export into Mattermost's bulk import format, and mmctl loads that file into the server. Run the conversion against a copy of the export and review the output before loading it into production. Users, channels, direct messages, threads and attachments are carried across, so the import validates the people and history side of the move, not the automation side.

Integrations do not migrate

The import does not carry Slack integrations, so every app installed in the workspace stops working on the day you cut over. Build a list of each installed app, its owner, the channels it posts to and the events it reacts to. Treat that list as the acceptance checklist for the cutover, and assign an owner to each item so that no integration goes unassigned. Expect the list to be longer than the apps page in Slack shows, because custom internal integrations often sit outside it.

Custom emoji and user groups

Custom emoji images and Slack user groups are not part of the Mattermost import. Export the emoji files separately and re-upload them, or confirm with the business owner which ones still matter. User groups used for mentions or permissions need to be recreated as Mattermost groups, and any workflow that depends on a group name will break until it is mapped. Record which groups drive notifications, approvals or channel access so they can be rebuilt in the same change window.

Slack Connect channels

Slack Connect channels shared with customers, partners or vendors do not migrate. Each external shared channel needs a decision: archive it, move the conversation to a channel your organization controls, or set up guest access in Mattermost with an agreed security review. Identify these channels from the workspace admin view before the export, since the external members and their data sit outside the import scope.

Inventory webhooks, commands and bot tokens

Make a register of every incoming webhook URL, slash command and bot token that Slack issued. Each webhook URL points to a Slack endpoint that stops receiving messages after cutover, so the producing system must be updated to a Mattermost incoming webhook URL. Slash commands and bot tokens need new definitions and credentials on the Mattermost side. Store the new secrets in your secrets manager, rotate the old Slack tokens, and test each producer against a staging channel before the production switch.

How to inventory, pilot and cut over Slack integrations in Mattermost

This sequence rebuilds Slack's apps, webhooks and bots on Mattermost in a controlled order, so each integration is inventoried, tested and retired only after its replacement has been proven. The output at each stage is a record you can review before cutover.

  1. Inventory every app, webhook, command and bot

    Start by listing everything that touches the Slack workspace: installed apps, incoming and outgoing webhooks, slash commands, workflow steps and bot users. For each item, record the owner, the channels it posts to, the trigger, the payload format and any mention or link syntax it uses. Ask workspace admins for the app directory and the integration logs, because a Slack export does not carry these items. The output is an inventory register with one row per integration and a named owner who confirms it. The register is done when the owners have signed off every row, including the ones they expected to be retired.

  2. Classify each integration by payload and dependency

    Group the register into three bands: webhooks that send plain text, webhooks that use Slack-only fields or formatting, and integrations that depend on Slack's own APIs, interactive buttons or modals. Mark the payload features each webhook uses, such as mrkdwn, link_names, parse or the <!everyone> and <!group> mentions. This classification tells you which items convert with little work and which need a rebuild. The output is a classified register that the team reviews with the owners. Confirm each feature against Mattermost's incoming webhook documentation rather than from memory.

  3. Pilot the conversion with mmetl on a sample export

    Export a representative set of public channels from Slack, then run mmetl against that sample to produce Mattermost's bulk import file. Load it into a non-production Mattermost server with mmctl and check that users, channels and attachments arrive as expected. Note that integrations do not migrate, so the pilot confirms your data path, not your bots. The output is a pilot log that records each command, any conversion warnings and the import result. Use the same Mattermost version you plan to run in production, and confirm the export plan you hold permits the channels you are testing.

  4. Rebuild and test each webhook against Mattermost rules

    Create each incoming webhook in Mattermost on a test channel and point the sending system at it. Send the payload in the form each integration uses, check that the Slack-style links and channel, here and all mentions are translated, and replace any unsupported mrkdwn, parse, link_names, group or channel-ID syntax with forms Mattermost accepts. Where a request has no Content-Type header, confirm whether the payload= prefix is needed. Record the request, the rendered message and the outcome in a test log. The step is complete when every webhook has a passing entry and each rebuilt item is marked in the register.

  5. Re-create slash commands and bots with owners

    Rebuild each slash command and bot as a Mattermost integration or a separately hosted service that the owner maintains. Slash commands and bots are not carried over by the migration, so each needs its own endpoint, token handling and permissions, and each should be reviewed against your identity and access rules. Run a test plan with real users in a pilot team, covering normal and failure cases. The output is a signed test record per command or bot and a list of any features that were dropped and accepted by the business owner.

  6. Run a parallel period with both platforms posting

    For a defined period, keep the Slack integrations live and send the same notifications to matching Mattermost channels. Compare delivery, formatting and timing for each integration, and log any mismatch in a shared defect list. Check that people reading the Mattermost channels receive the same information and that no message is lost or duplicated. The output is a parallel-run report that shows each integration's match rate and the defects still open. Agree the length of the parallel period with the owners in writing before it starts.

  7. Cut over and decommission Slack webhooks

    When the parallel report shows no open blocking defects and owners have approved, switch each sending system's endpoint from Slack to Mattermost and disable the Slack webhook. Revoke the Slack app tokens and remove the app from the workspace once its traffic has stopped. Keep the Slack export and the inventory register as an archive for the agreed retention period. The output is a cutover record listing each integration, the switch time, the revoked credential and the owner who signed it off.

Which Slack-style webhook payloads work unchanged in Mattermost

Most simple Slack-style incoming webhooks work in Mattermost without code changes, but only if the request is sent the way Mattermost expects. A request without a Content-Type header is read with the payload= prefix that Slack uses, so an existing sender that posts a URL-encoded JSON body keeps working. The icon_emoji parameter is supported from v5.14, so any integration relying on it is covered on current servers. Slack-style <url|text> links and the <!channel>, <!here> and <!all> mentions are translated on arrival. Senders that set a JSON Content-Type header are parsed as native Mattermost payloads, so the sender's header matters as much as its body.

The fields and forms that do not carry over fail quietly, which is why a message can post and still be wrong. Mattermost's incoming webhooks do not support Slack's mrkdwn, parse or link_names parameters, so a sender that depends on them loses its formatting or mention behavior without an error. The <!everyone> and <!group> mentions are not translated, and <#CHANNEL_ID> channel links are not rendered. Single-asterisk *bold* text is Slack's syntax and does not render as bold in Mattermost, where double asterisks are used. Each of these needs an edit in the sender, a change to the message template, or a decision to drop the feature.

Run a payload test for every integration before cutover, using a test channel and a copy of each real payload. Inventory the senders, record the exact fields and mention forms each one uses, then post the payload to a test webhook and compare the rendered result with what users see in Slack. Confirm the sender's Content-Type header, check that mentions notify the intended people, and check links and bold text. Treat a message that posts without error as unverified until a person has read it in the rendered channel. Keep the results in a short register so the platform team can show which integrations were changed and which were retired.

How the integration rebuild differs by Slack footprint

A small team with a handful of incoming webhooks usually has the lightest rebuild. Most of these are one-way notifications from monitoring, CI or a form tool that post a message into a channel. Mattermost accepts Slack-style payloads on its incoming webhooks, so many of these posts can keep their existing body once the webhook URL is replaced. The work is mostly inventory and verification rather than code.

  • Inventory the URLs: List every webhook in Slack, the channel it posts to, and the system that owns the sending code. Each one needs a new Mattermost webhook and a configuration change on the sender.
  • Check the payload format: Requests without a Content-Type header take the payload= prefix for Slack compatibility, so confirm which senders send that way and which send JSON.
  • Review formatting: Replace any *bold* single-asterisk text and any <!everyone> or <!group> mentions, since these are not supported on Mattermost incoming webhooks.
  • Test one message per channel: Post a test from each sender and confirm the text, links and mentions render as expected.

Before cutover, confirm with each owner that their sender can change its webhook URL without a release, and keep the old Slack URL active until every test message lands.

What drives the cost and duration of rebuilding Slack bots

This table lists the factors that change how much work it takes to rebuild Slack apps, bots and webhooks on Mattermost, and how to keep each one under control. Read each row as a question to answer in your own inventory before you ask for a quote. Mattermost Team Edition is free, but SSO and AD/LDAP sync sit in paid Professional plans, and Mattermost publishes no list prices, so the licensing line depends on a sales conversation.

DriverWhy it moves costHow to reduce it
Number of integrationsEach Slack app, webhook and slash command needs its own inventory entry, rebuild, test and owner sign-off, so effort grows with the count rather than with the message history.Export the list of installed apps and webhook URLs from Slack admin pages, then remove anything unused before any rebuild starts.
Custom code versus configurationApps built as custom Slack code need a new service on Mattermost, while simple incoming webhooks often need only a changed URL and payload check.Sort integrations into webhook-only, slash command and custom app groups, and rebuild the simplest group first.
Payload complexitySlack-style payloads that use mrkdwn, parse or link_names, <!everyone>, <!group>, <#CHANNEL_ID> links or single-asterisk bold need rewriting, and each rewrite needs a test.Search every webhook body for these forms and convert them to the Mattermost equivalents before cutover.
Identity mapping and SSOBots and slash commands act as or mention real users, so mapping Slack user IDs to Mattermost accounts takes work. SSO (SAML, OIDC, OAuth) and AD/LDAP sync are included from the Professional plan, so identity design can change the licence needed.Decide early whether accounts come from SSO or local login, build a user ID map from the migration export, and ask Mattermost which plan covers your identity model.
Slack Connect dependenciesSlack Connect channels and external integrations do not migrate, so any bot that posts into shared channels with partners needs a separate design, plus agreement from the external party.List every bot that posts to a Slack Connect channel and decide per channel whether it moves, is retired, or waits for a guest or federation design.
Testing and sign-offEach integration owner must confirm messages arrive in the right channel, with correct formatting, mentions and links. This is often the longest step because it depends on people outside the platform team.Assign a named owner per integration, write a short test script for each, and schedule sign-off windows before the cutover date.
Admin time and vendor quotesPlatform admins, app owners and security reviewers all carry time, and Mattermost sells paid editions through a sales conversation with no public prices, so the quote depends on the scope you define.Ask for a quote built from the integration inventory, the plan needed for SSO and sync, and the support hours for cutover, and confirm each assumption in writing.

What usually goes wrong when Slack bots move to Mattermost

Most failures in a Slack-to-Mattermost move happen at the edges: integrations that post the wrong formatting, mentions that reach the wrong people, and bots that keep running against a Slack workspace nobody is watching. Each card below names one of these failure points and the check that prevents it before cutover.

Webhook formatting breaks silently

Mattermost accepts Slack-style incoming webhook payloads, but not every Slack parameter carries over. Requests without a Content-Type header take the payload= prefix, and Slack-style <url|text> links translate, yet mrkdwn, parse and link_names are not supported and *bold* with a single asterisk will not render as Slack users expect. Send a test payload from every webhook to a staging channel and compare the rendered output with what the Slack version showed.

Mentions notify the wrong people

Mattermost translates <!channel>, <!here> and <!all>, but <!everyone>, <!group> and <#CHANNEL_ID> channel links are not supported. A bot that posted <!everyone> in Slack may post plain text in Mattermost, so nobody is paged. Search every webhook and bot configuration for these forms and rewrite them to the Mattermost equivalents, then confirm that the on-call alias still receives a notification in a test channel.

Bots still running against Slack

After decommission, a Slack app can keep reading channels, posting alerts or holding a token that a former employee created. Inventory every Slack app with its installing user, scopes and channels, then revoke or disable each one in the same change window that closes the Slack workspace. Ask the Slack workspace owner to confirm the list is complete, since integrations do not appear in a channel export.

User groups lost in migration

The Mattermost Slack migration does not carry user groups across. Any workflow that routes approvals, on-call pages or access reviews to a Slack user group will stop reaching the intended team after import. Export the membership of each group from Slack, recreate the groups in Mattermost, and update every routing rule that referenced them before users start working in the new server.

History imported without its integrations

Messages from bots, alerts and approvals arrive in the import, but the apps that generated them do not. Users then see archived alerts with no way to act on them, and searches return context that points to integrations that no longer exist. Decide which historic channels need live integrations, and document which integrations were intentionally left behind so auditors and staff can see the gap was a decision.

Version drift after go-live

Mattermost releases a new server version in binary form on the 16th of each month, and v11.7 is an Extended Support Release supported until 2027-05-15. A bot tested on one release can break after an upgrade. Pin the server to a version you have tested, record which release that is, and schedule upgrades in a staging environment so integrations are retested before each production change.

What to confirm with Mattermost and your app owners before committing

Before you commit to Mattermost, confirm for every Slack integration whether a Mattermost-compatible replacement already exists or whether it must be rebuilt. Third-party Slack apps often rely on features that incoming webhooks do not carry over, such as mrkdwn, parse and link_names, or on <!everyone>, <!group> and <#CHANNEL_ID> formatting. Ask each app owner or vendor which Slack API methods the app calls, whether it uses slash commands, interactive message buttons or the Events API, and whether it needs a Mattermost bot account or an incoming webhook. Apps that depend on Slack's OAuth installation flow will not move by export alone, so treat them as rebuild items and record the owner, the target design and the test sign-off for each one.

Slack Connect channels need a separate decision. Mattermost's migration path does not carry Slack Connect channels, so confirm with business owners which external partners and customers still need a shared space after cutover. Options include inviting those people as guests on your Mattermost server, moving the conversation to a different channel the partner already uses, or keeping the Slack connection until the partner agrees to move. Record the data handling terms that apply to any external conversation before the cutover date, since the partner's own workspace policies will not change because yours did.

Decide where custom code runs and who owns it. Bots and webhook senders that your teams wrote usually live in a repository, a serverless function or a cron job on a server that already has Slack credentials. Confirm which of these are in scope, where they will be hosted inside your own network, how their secrets move to your secrets store, and who approves changes to the webhook URLs. Finally, verify current payload behavior against the Mattermost incoming webhooks documentation and run your own test payloads in a staging channel, covering attachments, emoji icons and mentions, because the documented compatibility list is the reference your app owners will be held to.

Questions teams ask before moving Slack apps to Mattermost

Do Slack apps and integrations migrate to Mattermost automatically?

No. Integrations do not move with a Slack export. Mattermost's documented Slack migration path, which converts an export with mmetl and loads it with mmctl, brings across users, channels, direct messages, threads and attachments, but not integrations, custom emoji images, user groups or Slack Connect channels. Every app, bot, slash command and webhook needs an inventory and a rebuild on the Mattermost side before cutover. Confirm the current import scope in the Mattermost Slack migration guide against your own export before you plan the work.

Which Slack export plan do we need to rebuild integrations?

The export plan does not decide whether integrations can be rebuilt, but it decides what history you can carry over. Every Slack plan can export messages and file links from public channels. Private channels and direct messages require a Business+ or Enterprise plan, and custom exports by member or conversation are limited to Enterprise. If your bots post into private channels or depend on DM history, confirm your export tier early, because an approved export request is a prerequisite for moving that content. Slack's export help article lists the options for each plan.

How much effort does rebuilding Slack integrations take, and what drives it?

Effort depends on the number of integrations, how much each one relies on Slack-specific behavior, and who owns the code. Simple incoming webhooks that send plain text often need only a URL change. Bots that use slash commands, interactive buttons, Slack formatting or the Slack API need redesign. Mattermost's incoming webhooks accept Slack-style payloads, but not every Slack field or mention form works, so each integration should be tested against its real payloads. Ask for a written inventory with a complexity rating per integration. No general duration is reliable without that list, because the number of unique integrations drives the work more than seat count.

Can our own team rebuild the Slack apps without outside help?

Often yes, if the team has developers who know the apps and access to their source code, and if the integrations are simple. Teams with a small number of webhooks usually handle the URL change and payload tests in house. Outside help adds value when bots use Slack features that Mattermost does not translate, when many business owners depend on the apps, or when the cutover must be tested under a fixed schedule. DeployOpen plans, implements, customizes, integrates and documents self-hosted platforms in your infrastructure and works under a fixed scope agreed in writing before work starts, so you can decide which integrations to keep in house and which to scope out.

What do app owners need to provide during the rebuild?

App owners need to confirm what each integration does, who depends on it, which channels it posts to, what credentials and scopes it uses, and what success looks like after cutover. They also need to provide access to the code, deployment environment and any secrets stored in Slack-side configuration. Owners should list every outbound call and inbound trigger, because webhook-only integrations are easy to miss in an export. Assign a named owner to each integration so testing and sign-off happen before the old Slack app is turned off.

How should we handle Slack Connect channels and user groups during the move?

Plan these separately, because neither moves with the standard export path. Slack Connect channels shared with customers or partners do not migrate, so you need an agreed replacement, such as guest accounts in Mattermost, and a security review of who gets access. User groups do not migrate either, so any mention, notification or access rule that used a group must be recreated as a Mattermost team, channel or group. Ask each owner which Slack Connect channels and user groups they rely on, and record the replacement decision before the cutover date.

Which Slack mention and formatting forms break in Mattermost webhooks?

Several do. Mattermost's incoming webhooks translate Slack-style links in the form of a URL with text and the channel, here and all mentions, but they do not support Slack's mrkdwn, parse and link_names parameters, the everyone and group mentions, channel links by ID, or single-asterisk bold. Engineers should search every integration for these forms and rewrite them, then test each message in a staging channel. Check the Mattermost incoming webhooks documentation for the exact supported set before you change code.

How DeployOpen scopes and runs a Slack to Mattermost integration migration

DeployOpen plans and implements a self-hosted Mattermost server inside the client's own infrastructure, then takes on the integration work that a Slack export does not carry across. In practice that means an inventory of every Slack app, slash command, incoming webhook and bot in use, a decision for each one (rebuild as a Mattermost webhook, rebuild as a slash command or bot account, or retire), and the code and configuration changes needed to make each one work. Engagements run under a fixed-scope written agreement that names the in-scope integrations, the deliverables, the test cases and the cutover criteria before work starts. DeployOpen also customizes and hardens the server, tests the rebuilt integrations, backs up the database and file storage, and documents the result. Ongoing upgrades, monitoring and continuous testing are available as a retainer, which matters because Mattermost publishes new server versions monthly and tracks support windows for each release.

Ask any provider, DeployOpen included, to show the integration inventory before agreeing on price. The inventory should record the Slack app name, who owns it, which channels it posts to, whether it uses attachments, blocks, mrkdwn or link_names, and whether it reads data back from Slack. Those answers determine the effort. A webhook that sends plain text with <!channel> mentions usually needs little change, while a bot that relies on Slack's Web API, interactive buttons or user groups is a rebuild. Confirm with your own security team which secrets, service accounts and network paths each integration needs, and where the webhook endpoints will live, since those controls are part of the hardening and testing scope. Also confirm the Slack plan your workspace is on, because it limits what history and private channel data can be exported in the first place. Any quote should separate the one-time build and cutover work from the recurring hosting, upgrade and support costs, and state which Mattermost edition the design assumes, because SSO and clustering are paid features.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.