Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
With Microsoft Graph, you can migrate users' existing message history and data from an external system into Teams. Users can continue their communications in a seamless manner and proceed without interruption by enabling the recreation of a third-party platform messaging hierarchy inside Teams.
Permissions
| Scope name | Display name | Description | Type | Admin consent required | Entities/APIs covered |
|---|---|---|---|---|---|
| Teamwork.Migrate.All | Manage migration to Microsoft Teams | Creating and managing resources for migration to Teams. | Application-only | Yes | POST /team |
Note
Delegated authentication isn't supported.
Supported channel and chat types
Teams supports migrating external message to existing channels or chats. Use any channel or chat that already exists in Teams, regardless of when you created it. This approach lets you add existing context to channels that are already active in Teams and maintains continuity for ongoing conversations. To enable migration mode in an existing channel or chat, see Existing channel migration.
Note
Federated content can't be imported. All imported content must come from the authenticated tenant.
The application that calls startMigration on a thread owns that migration session end-to-end. The same app must invoke importMessage and completeMigration. No other app can call these APIs on the thread until the owning app completes migration.
migrationMode is a special state that ensures data integrity by preventing certain operations during data migration.
- For all supported channels and chat types:
- It allows importing historical messages with custom timestamps
- It maintains the original conversation structure and hierarchy
Content scope for import
The following table provides the content scope for existing channels and chats.
| In-scope | Out-of-scope |
|---|---|
| Team (general) | Announcements |
| Created time of the original message | Videos |
| Inline images as part of the message | Stickers |
| Links to existing files in Microsoft 365 (Microsoft 365) SharePoint Online (SPO) or OneDrive (OD) | Cross posts between channels |
| Messages with rich text | |
| Message reply chain | |
| High throughput processing | |
| 1:1 and group chat messages | |
| Standard, private, and shared channel messages | |
| Up to 250 reactions | |
| @mentions and emojis | |
| Code snippets | |
| Quotes |
Prerequisites
Analyze and prepare message data
- Review the third-party data to decide what to migrate.
- Extract the selected data from the third-party chat system.
- Map the third-party chat structure to the Teams structure.
- Convert import data into the format needed for migration.
Set up your Microsoft 365 tenant
- Ensure that a Microsoft 365 tenant exists for the import data. For more information on setting up a Microsoft 365 tenant for Teams, see prepare your Microsoft 365 tenant.
- Make sure that team members are in Microsoft Entra ID. For more information, see add a new user to Microsoft Entra ID.
Import historical messages into Teams
You can import historical messages seamlessly into existing channels or chats by performing the following steps:
- Start migration
- Check migration status
- Import messages
- Complete migration mode
- Verify migration mode completion
Step 1: Start migration
To start migrating a user's message history from any third-party platform to Teams, you can use an existing channel or chat.
Start migration on existing channels and chats
On existing channels or chats, use the startMigration API to enable channel migration mode or to enable chat migration mode
startMigration sets the migration state to InProgress and begins the message import process. For more information, see:
Existing channel migration
To enable migration mode on existing channels, use the startMigration API.
Request (existing channel in migration mode)
POST https://graph.microsoft.com/beta/teams/{team-id}/channels/{channel-id}/startMigration
{
"conversationCreationDateTime":"2024-01-01T00:00:00Z"
}
Tip
Microsoft Graph uses DateTimeOffset to represent date and time with a UTC offset for an accurate time zone.
The conversationCreationDateTime value must be greater than the minimum value for DateTimeOffset and less than the current value of the channel's createdDateTime.
Response
If the request is successful, the method returns an empty HTTP response.
HTTP/1.1 204 No Content
Example
POST https://graph.microsoft.com/beta/teams/57fb72d0-d811-46f4-8947-305e6072eaa5/channels/19:4b6bed8d24574f6a9e436813cb2617d8@thread.tacv2/startMigration
{
"conversationCreationDateTime":"2024-01-01T00:00:00Z"
}
Existing chat migration
To enable migration mode on existing chats, use the startMigration API.
Request (existing chat in migration mode)
POST https://graph.microsoft.com/beta/chats/{chat-id}/startMigration
{
"conversationCreationDateTime":"2024-01-01T00:00:00Z"
}
Tip
Microsoft Graph uses DateTimeOffset to represent date and time with a UTC offset for an accurate time zone.
The conversationCreationDateTime must be greater than the minimum value for DateTimeOffset and less than the current value of the chat's createdDateTime.
Response
If the request is successful, the method returns an empty HTTP response.
HTTP/1.1 204 No Content
Example
POST https://graph.microsoft.com/beta/teams/57fb72d0-d811-46f4-8947-305e6072eaa5/chats/19:4b6bed8d24574f6a9e436813cb2617d8@thread.tacv2/startMigration
{
"conversationCreationDateTime":"2024-01-01T00:00:00Z"
}
Consider the following important points:
- Define a minimum timestamp for messages to migrate. The provided timestamp must be older than the channel or chat's current
createdDateTime. This timestamp replaces the existingcreatedDateTimeof the channel. If you updatecreatedDateTimeto a past timestamp, you can't move it to a future timestamp again. - The
creationDateTimeproperty is optional in a request body. If omitted, thestartMigrationAPI uses the current date and time as the minimum timestamp. - The
startMigrationAPI starts the message migration process by setting the migration mode toInProgressfor a specified channel or chat.
Step 2: Check migration status
Call Get channel or Get chat to confirm that the migrationMode state is set to InProgress. For more information, see:
You can also verify that target chat or channel is in migrationMode state in Teams through a banner which says Migration for this conversation is in progress. Messages may be out of order during this time.
This banner will remain visible in the Teams UI until the migration is completed for the target chat or channel.
Note
The migrationMode flag is currently available only in the beta version.
Step 3: Import messages
Now you can import back-in-time messages by including the createdDateTime and from keys in the request body.
Note
- The API doesn't support messages imported with a creation date and time earlier than the
createdDateTimefor the message thread. createdDateTimemust be unique across messages in the same thread.createdDateTimesupports timestamps with milliseconds precision. For example, if the incoming request message hascreatedDateTimeset to 2020-09-16T05:50:31.0025302Z, the API converts it to 2020-09-16T05:50:31.002Z when ingesting the message.
Request (POST message that is text-only)
POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/messages
{
"createdDateTime":"2019-02-04T19:58:15.511Z",
"from":{
"user":{
"id":"id-value",
"displayName":"John Doe",
"userIdentityType":"aadUser"
}
},
"body":{
"contentType":"html",
"content":"Hello World"
}
}
Response
HTTP/1.1 200 OK
{
"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#teams('team-id')/channels('channel-id')/messages/$entity",
"id":"id-value",
"replyToId":null,
"etag":"id-value",
"messageType":"message",
"createdDateTime":"2019-02-04T19:58:15.58Z",
"lastModifiedDateTime":null,
"deleted":false,
"subject":null,
"summary":null,
"importance":"normal",
"locale":"en-us",
"policyViolation":null,
"from":{
"application":null,
"device":null,
"conversation":null,
"user":{
"id":"id-value",
"displayName":"Joh Doe",
"userIdentityType":"aadUser"
}
},
"body":{
"contentType":"html",
"content":"Hello World"
},
"attachments":[
],
"mentions":[
],
"reactions":[
]
}
Error message
You receive the following error message if you set the createdDateTime property to a future date and time.
400 Bad Request
Request (POST message with an inline image)
Note
- There are no special permission scopes in this scenario since the request is part of
chatMessage. - The scopes for
chatMessageapply here.
POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/messages
{
"body": {
"contentType":"html",
"content": "<div><div>\n<div><span><img height=\"250\" src=\"../hostedContents/1/$value\" width=\"176.2295081967213\" style=\"vertical-align:bottom; width:176px; height:250px\"></span>\n\n</div>\n\n\n</div>\n</div>"
},
"hostedContents":[
{
"@microsoft.graph.temporaryId":"1",
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAANcAAAExCAYAAADvFzeeAAAXjklEQVR4Ae2d/XNU1RnH+9e0FFrA0RCIyaS8hRA0HV5KbS1gHRgVpjMClY4GHJ3yYm1HCmXaWttaaZUZtIIFKYi8lFAkvOQ9u5vN225IARVBbX9/Os9NbrLZbMjmhCfJPX5+2Lmb3T25y3O+n/M599x7w9f+++UXwoMakIF7n4GvUdR7X1RqSk01A8CFuZm5GGUAuIwKi72wF3ABF+YyygBwGRUWc2Eu4AIuzGWUAeAyKizmwlzABVyYyygDwGVUWMyFuYALuDCXUQaAy6iwmAtzARdwfWXMdeuzT+TGxz3Sfb1LunrapL07IW3pePDQ5/qavqef0c+OdYAELuAac4jGGkLL9rdvfyo9N9ODQAqBGmmrwGlb/R0u3xG4gMspOC5hG882CoRaaCSA8n1ff9doIQMu4PIOrus3u+8ZVNnw6e/Od5AALuDKOyz5hmqiPnfnzi1J9bSbgRWCpvvQfY307wQu4BoxJCOFaDK8rwsQmQsUIQhWW93XSIsewAVckYdLQ24F0Ui/926AARdwRRounZ6Np7GyYdN9DzdFBC7gijRc43GMlQ1U9s/6HXJNjYELuHI<<-----Removed----->>>>",
"contentType": "image/png"
}
]
}
Response
HTTP/1.1 200 OK
{
"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#teams('team-id')/channels('channel-id')/messages/$entity",
"id":"id-value",
"replyToId":null,
"etag":"id-value",
"messageType":"message",
"createdDateTime": "2019-02-04T19:58:15.511Z",
"lastModifiedDateTime":null,
"deleted":false,
"subject":null,
"summary":null,
"importance":"normal",
"locale":"en-us",
"policyViolation":null,
"from": {
"application":null,
"device":null,
"conversation":null,
"user": {
"id":"id-value",
"displayName":"John Doe",
"userIdentityType":"aadUser"
}
},
"body": {
"contentType":"html",
"content":"<div><div>\n<div><span><img height=\"250\" src=\"https://graph.microsoft.com/teams/teamId/channels/channelId/messages/id-value/hostedContents/hostedContentId/$value\" width=\"176.2295081967213\" style=\"vertical-align:bottom; width:176px; height:250px\"></span>\n\n</div>\n\n\n</div>\n</div>"
},
"attachments":[],
"mentions":[],
"reactions":[]
}
Step 4: Complete migration mode
For existing channels or chats already in migration mode, use the completeMigration API to mark the migration state as completed. This process ensures that the channel or chat remains permanently available instead of being dropped after migration.
Request (complete existing channel migration)
POST https://graph.microsoft.com/beta/teams/{team-id}/channels/{channel-id}/completeMigration
Response
HTTP/1.1 204 NoContent
Request (complete existing chat migration)
POST https://graph.microsoft.com/beta/chats/{chat-id}/completeMigration
Response
HTTP/1.1 204 NoContent
Optional: Update group chat member history after migration
When you complete message migration in a group chat, you can optionally update members’ share history by using the visibleHistoryStartDateTime property in Microsoft Graph. This property sets the earliest time a chat member can view messages in a conversation. If imported messages are older than the property's value, they don’t appear unless you update the property.
To update the visibleHistoryStartDateTime property:
- Remove the member from the chat.
- Add the member back with a new
visibleHistoryStartDateTimethat includes the imported messages.
Example
Consider a scenario where the original chat was created at 10 PM, updated at 1 AM, messages were imported at 9 AM, and member A’s share history starts at 10 AM. To ensure that member A can see the 9 AM imported messages:
- Remove member A from the chat.
- Add member A with the
visibleHistoryStartDateTimeproperty set before 9 AM.
Step 5: Verify migration mode completion
Call Get channel or
Get chat to verify that the migrationMode is marked as Completed.
Tips and additional information
- After calling
completeMigrationon an existing channel or chat, you can continue importing messages by using thestartMigrationAPI.
Throttling: Messages import at five RPS per channel.
If you need to correct the migration results, you must delete the Teams, repeat the steps to create the Teams and channel, and re-migrate the messages.
Note
Inline images are the only type of media supported by the import message API schema.
Code sample
| Sample name | Description | Node.js | C# | Python |
|---|---|---|---|---|
| Graph chat migration | This sample app can be used to migrate historical messages from external platforms to Teams. | View | View | NA |
See also
Platform Docs