SShareShiftby Cameron Shields
Teams and Planner

Teams migration tool guide: channels, timestamps and chats

How migration mode imports channel posts with original authors and timestamps, why private channels need a different route, and why chats become archives.

By Cameron ShieldsPublished 8 September 20269 minute read

Microsoft Teams is the workload where migration tools differ most, because Microsoft Graph draws a hard line through it. Channel conversations can be imported as real posts with their original authors and timestamps, using an API Microsoft built for exactly that. Chats cannot be re-created by any supported means. Everything a Teams migration tool claims should be read against that line, and this guide explains where it falls, what each side allows, and how the two best-known approaches, native import and an HTML archive tab, compare in practice. The API behaviour described here was verified live against a Microsoft 365 tenant in September 2026.

Migration mode: how channel history is imported

Graph's import-third-party-platform-messages API lets an application create a team or channel in migration mode, post messages carrying an original createdDateTime and an original from user, and then complete the migration, at which point the channel becomes an ordinary channel with a back-dated history. Teams renders those posts exactly as if the people had written them on those dates.

  1. Create the destination team with teamCreationMode: migration and the source team's creation date, or use an existing team.
  2. Create each channel in migration mode with its source creation date. On an existing team, put a same-named channel into migration mode with startMigration and a conversationCreationDateTime.
  3. Read the source channel with getAllMessages or the channel messages endpoint, oldest first, with replies.
  4. Import each root post and its replies with the original timestamp to the millisecond, the original author resolved by UPN, the body, and inline images as hosted content. Unresolved authors (people who have left, guests without a user object) are imported by display name, and Teams shows that name on the post.
  5. Call completeMigration on each channel and then on the team. Only after completion can members be added, because a team in migration mode rejects membership changes.

Microsoft's constraints are specific: application permission Teamwork.Migrate.All, a limit of 5 requests per second per channel, inline images only as media, and the same app must start, import and complete. The Teams export APIs used to read the source stopped being metered on 25 August 2025; whether a protected API access request is still needed for ChannelMessage.Read.All varies by tenant, and it worked without one in testing.

Two behaviours matter for correctness. Graph keys imported posts by the original timestamp in epoch milliseconds and answers 409 Conflict on a duplicate, so a re-run never produces duplicate posts even if the tool's state is lost. And Graph rejects any post older than the channel's back-dated creation time with a 403 MessageWritesBlocked error, so the conversation creation date has to be set a moment before the oldest post, and the back-dating can take up to about 90 seconds to propagate before importing can start.

Microsoft states that a Teams message import cannot be corrected in place: to redo an import you delete and recreate the team or channel. Pilot on a test team first, and keep the tool's state file so re-runs skip what is already there.

Private and shared channels

Private channels have no migration mode of their own. Creating a channel with channelCreationMode: migration and membershipType: private is accepted by Graph but silently creates a standard channel with no roster, which was verified live and is the kind of behaviour that makes a private channel migration look successful when it is not. What works is to create the private channel normally with its mapped owners after the team is completed, put it into migration mode with startMigration, import the posts and replies exactly as for a standard channel, complete it, then add the mapped members and owners.

Each private channel has a SharePoint site of its own, provisioned asynchronously ten to twenty seconds after creation. The files in it are a separate library migration, so the tool needs to report the source and destination site pair for every private channel so the file run can be pointed at them. Shared channels are different: Graph has no migration mode for them and their membership spans tenants, so they are reported and skipped by ShareShift and listed as unsupported by ShareGate.

What carries and what does not

ItemNative import (migration mode)Notes
Team, channels, membershipYesOwners first, after completion; a 404 in the first seconds after completion is a propagation delay
Channel filesYes, through the SharePoint library migrationEach channel maps to a folder in the team site; private channels have their own site
Posts and replies with original date and authorYesMillisecond timestamps; departed authors shown by display name
Subjects, formatting, inline imagesYesInline images re-hosted; images above a size limit replaced by a note
ReactionsNoNot part of the import payload; ShareShift appends a compact reactions line to the post body
MentionsFlattened to the nameThe import payload has no mentions element for application imports
File attachmentsAs linksOnly inline images are accepted as hosted content; links can be rewritten to the migrated library
Edited timestampNoOnly the original creation time is carried
System messages, deleted postsSkipped and counted
Adaptive cards and bot postsCards not re-created; bot authors by display name
Tabs, apps, wikiNot covered by message importShareGate copies tabs and apps but not Wiki or Flow tabs, and does not preserve tab order
Shared channelsNoNo migration mode; membership spans tenants

The alternative: an HTML message history tab

ShareGate takes a different route. Its Teams copy writes conversations to an HTML “Message history” tab in the destination channel, and posts only the 50 most recent conversations to the channel itself, or 500 through PowerShell. Reactions, link previews and mention resolution are lost, Wiki and Flow tabs are unsupported, tab order is not preserved, and shared channels are unsupported. The approach is documented in ShareGate's help centre, and it is a legitimate design for a team that only needs history to be findable.

The difference shows up in daily use. With native import, a channel opened in the destination reads like it always did: the posts are there, in order, under the right names and dates, searchable and threadable. With an HTML tab, the history is a document the team has to go and open, and the channel timeline starts at the migration with a few dozen posts pasted in. If a project's users will notice the difference, and in a merger they will, ask each vendor which route they use and what the limits are.

Why chats become archives

The import API exists for team channels only. There is no migration mode for 1:1, group or meeting chats, and an application cannot even post an ordinary message: POST /chats/{id}/messages with an app-only token answers 401 Message POST is allowed in application-only context only for import purposes. So a chat cannot be re-created in the destination with its original authors and timestamps by any supported route.

ShareGate shipped a private chat copy and then disabled it “until further notice” on 5 May 2026 because of history visibility defects: members who join a re-created chat could see history they should not. ShareShift is explicit that chats are archives. It exports one self-contained HTML file per chat (participants with UPNs, every message oldest first with author and UTC timestamp, quoted replies, attachment names as links, reactions, inline images embedded) plus a JSON sidecar, and can post each archive into a private channel whose members are the mapped participants, so the history is private to the people who were in it.

If personal chats must move as live chats, the supported route is Microsoft's own Migration Orchestrator, in public preview since December 2025, which moves 1:1 and group chats between tenants with the per-user Cross-tenant User Data Migration licence but does not migrate channels or SharePoint sites. Pairing it with a channel tool is the honest design; the tenant to tenant guide sets it out.

Running a Teams migration

  • Grant the Graph application permissions: Teamwork.Migrate.All, Group.ReadWrite.All, ChannelMessage.Read.All, TeamMember.ReadWrite.All, Channel.ReadBasic.All, Channel.Create, ChannelMember.ReadWrite.All, User.Read.All, and Chat.Read.All plus ChatMessage.Read.All for chat archives. Allow about five minutes after consent before tokens carry the roles.
  • Build the user mapping with domain rewrites for cross-tenant, and expect a warning list of unmapped or departed authors.
  • Pilot on one team with a private channel. Read the destination back and check timestamps to the millisecond, author names, an inline image and the private channel roster.
  • Run channels, then the channel file libraries, then Planner plans attached to the team; see Planner migration.
  • Keep the state file. A re-run posts only what is missing, and Graph's duplicate detection covers the rest.

ShareShift includes Teams standard and private channels with native import on every plan, alongside SharePoint, OneDrive, file shares and Planner, at half the price of ShareGate Essentials; the ShareGate comparison covers the Teams differences line by line, and the pricing page has the 30-day trial.

Frequently asked questions

Can Teams channel messages be migrated with original timestamps?

Yes. Microsoft Graph's migration mode lets an application import posts and replies with the original createdDateTime and author into a team or channel in migration mode, then complete the migration. The limit is 5 requests per second per channel and only inline images are accepted as media.

Can Teams private chats be migrated?

Not as live chats by any supported third-party route: Graph refuses app-only message posts to chats except for import, and there is no import mode for chats. ShareGate disabled its private chat copy on 5 May 2026. Options are HTML archives, or Microsoft's Migration Orchestrator with per-user licences.

Do private channels migrate?

Yes, with a different sequence. Migration-mode creation silently produces a standard channel, so the private channel is created normally with owners, back-dated with startMigration, imported, completed, and then its roster is added. Its SharePoint site is migrated separately.

How does ShareGate handle Teams conversations?

It writes them to an HTML message history tab in the destination channel and posts the 50 most recent conversations (500 via PowerShell) to the channel. Reactions, link previews and mention resolution are lost; shared channels, Wiki and Flow tabs are unsupported.

What happens to reactions and mentions?

The import payload has no reactions or mentions element for application imports. Mentions are flattened to the name. ShareShift appends a compact reactions line to each post that had reactions; chat archives list reactions per message.

Related reading
Try ShareShift

Run your first migration on a 30-day free trial

Every workload, unlimited data, three workers, pause and resume built in. Worker-only, so your content never passes through our servers. The trial key is issued from the portal and works with the same app you would buy.

Teams migration tool guide: channels, timestamps, chats · ShareShift