MigrationFox Docs

Slack to Teams migration

Bring your Slack channels, channel messages, and shared files into Microsoft Teams with original timestamps and sender attribution preserved. This guide walks through the credential setup, the wizard flow, the workspace-to-team mapping rules, and the Slack and Microsoft API limits that shape what a Slack-to-Teams migration can and cannot carry across.

Before you start

MigrationFox uses Microsoft's Teams Migration API to import messages with original metadata. That API imports channel messages only — it does not accept direct messages. Plan for DMs to stay in Slack as a read-only archive, or export them separately for records retention.

What this migration carries across

What does not migrate

Prerequisites

Source — Slack

Workspace admin access or a Slack app with read scopes

What to grant: either connect with a Slack workspace admin account, or register a Slack app (Apps → Create New AppFrom scratch) with the following bot token scopes:

  • channels:read — list public channels
  • channels:history — read message history in public channels
  • users:read — resolve Slack user IDs to names and emails for mapping

Install the app into your workspace and provide the bot token to MigrationFox when prompted. The app must be installed by a workspace admin for the scopes to take effect.

Why these specific scopes: they are the minimum needed to enumerate channels, read their message history, and resolve user identities. MigrationFox does not request write scopes against Slack at any point.

Destination — Microsoft Teams

Azure AD app with Teamwork.Migrate.All

What to grant:

  1. Register an Azure AD app (or reuse the one you already use for MigrationFox).
  2. Under API permissions, add Teamwork.Migrate.All as an Application permission.
  3. Click Grant admin consent for the destination tenant.

Why application permission: the Teams Migration API only accepts app-only tokens. Delegated tokens cannot write imported messages with original timestamps.

User mapping

Slack identity → Microsoft 365 UPN

Slack user IDs (e.g. U0ABC1234) are opaque. Microsoft Teams needs a real UPN (e.g. jane@contoso.com) to attribute an imported message. Prepare a mapping list before you start so the wizard can validate it up front.

Export Slack members with their emails from your workspace directory, then match each row to the Microsoft 365 UPN that owns the same mailbox. Unmapped users cause their messages to import under a default sender rather than the intended user — fix before running, not after.

Wizard flow

The Slack-to-Teams wizard in MigrationFox runs in the same shape as any other migration job. Each step is resumable — if you close the tab mid-way, you pick up where you left off the next time you open the job.

  1. Add credentials. Add the Slack credential (bot token from your app, or OAuth sign-in as a workspace admin) and the Microsoft credential (OAuth with admin consent on the destination tenant). Both are validated before you can continue.
  2. Select source workspace and channels. MigrationFox enumerates every public channel the credential can see. Private channels require the credential to be a member; see Known limits below.
  3. Configure user mapping. Upload or paste your Slack-to-UPN mapping. The wizard flags unmapped active users before letting you proceed.
  4. Pick or create the destination team. You can target an existing team or have MigrationFox provision a new one. A new team is created in migration mode (the Teams flag that lets historical timestamps land) and flipped to active after the import completes.
  5. Review and start. The job runs channel-by-channel: channels are created first, messages import in order, and each channel's file attachments queue as a companion SharePoint job on the team's backing site.

Workspace-to-team mapping rules

A Slack workspace does not line up 1:1 with a Teams team. The wizard gives you two supported shapes:

Channel name collisions — for example #general already existing on the target team — are flagged before run. The wizard proposes a renamed destination channel; you can accept the suggestion, edit it, or skip that channel.

Known limits

Slack free tier: 90-day visible history

On the free Slack plan, messages older than 90 days are hidden from the workspace and cannot be read back through the API, even with full admin scopes. Only messages in the visible 90-day window will migrate. Upgrading to a paid Slack plan before running the migration unlocks the full history; this is the single most common cause of “most of our messages didn't come over.”

Troubleshooting

SymptomLikely causeFix
Channel enumeration returns far fewer channels than the workspace has The Slack credential lacks channels:read, or private channels exist that the user is not a member of. Verify the Slack app has channels:read installed; add the migration user to the private channels that matter; rerun the scan.
Messages older than roughly 90 days are missing Slack free-tier history retention; older messages are not returned by the API. Upgrade the Slack workspace before running the migration, or accept that only the visible 90-day window will migrate.
Migration fails with “Teamwork.Migrate.All not granted” or HTTP 403 on channel creation The Azure AD app has the permission but admin consent was never clicked; or the consent was granted in the wrong tenant. Go to Azure AD → your app → API permissions → Grant admin consent. Confirm you are in the destination tenant.
All imported messages show the same sender (a default user) instead of the original Slack author The user mapping had Slack IDs or emails that did not match any UPN in the destination tenant. Export the mapping from the job page, fix the unmatched rows, and re-run. Mapping changes only apply on fresh runs — already-imported messages keep the attribution they landed with.
Channel imports but files never appear in the Teams channel's Files tab The companion SharePoint file job hasn't finished yet, or the destination site storage quota is full. Check the file job's status on the job detail page; companion jobs run after the message import, so expect a delay on large channels. Resolve any SharePoint quota error and the job resumes.
A channel is reported as “name invalid” by the wizard The Slack channel name contains characters Teams rejects (e.g. #, certain punctuation) or collides with an existing team channel. Accept the suggested rename in the wizard or edit it. Teams channel naming rules are stricter than Slack's — the wizard tells you exactly what it will use.
Emoji reactions and threaded reply structure are missing after migration Expected — the Microsoft import API does not accept reactions and flattens threads. Not fixable at the API layer. Treat this as a documented limit, communicate to end users before cutover.

Related