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.
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.
- Create the destination team with
teamCreationMode: migrationand the source team's creation date, or use an existing team. - Create each channel in migration mode with its source creation date. On an existing team, put a same-named channel into migration mode with
startMigrationand aconversationCreationDateTime. - Read the source channel with
getAllMessagesor the channel messages endpoint, oldest first, with replies. - 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.
- Call
completeMigrationon 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.
What carries and what does not
| Item | Native import (migration mode) | Notes |
|---|---|---|
| Team, channels, membership | Yes | Owners first, after completion; a 404 in the first seconds after completion is a propagation delay |
| Channel files | Yes, through the SharePoint library migration | Each channel maps to a folder in the team site; private channels have their own site |
| Posts and replies with original date and author | Yes | Millisecond timestamps; departed authors shown by display name |
| Subjects, formatting, inline images | Yes | Inline images re-hosted; images above a size limit replaced by a note |
| Reactions | No | Not part of the import payload; ShareShift appends a compact reactions line to the post body |
| Mentions | Flattened to the name | The import payload has no mentions element for application imports |
| File attachments | As links | Only inline images are accepted as hosted content; links can be rewritten to the migrated library |
| Edited timestamp | No | Only the original creation time is carried |
| System messages, deleted posts | Skipped and counted | |
| Adaptive cards and bot posts | Cards not re-created; bot authors by display name | |
| Tabs, apps, wiki | Not covered by message import | ShareGate copies tabs and apps but not Wiki or Flow tabs, and does not preserve tab order |
| Shared channels | No | No 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, andChat.Read.AllplusChatMessage.Read.Allfor 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.
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.