Edit

Share via


Import third-party platform messages to Teams using Microsoft Graph

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:

  1. Start migration
  2. Check migration status
  3. Import messages
  4. Complete migration mode
  5. 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 existing createdDateTime of the channel. If you update createdDateTime to a past timestamp, you can't move it to a future timestamp again.
  • The creationDateTime property is optional in a request body. If omitted, the startMigration API uses the current date and time as the minimum timestamp.
  • The startMigration API starts the message migration process by setting the migration mode to InProgress for 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 createdDateTime for the message thread.
  • createdDateTime must be unique across messages in the same thread.
  • createdDateTime supports timestamps with milliseconds precision. For example, if the incoming request message has createdDateTime set 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 chatMessage apply 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:

  1. Remove the member from the chat.
  2. Add the member back with a new visibleHistoryStartDateTime that 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:

  1. Remove member A from the chat.
  2. Add member A with the visibleHistoryStartDateTime property 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 completeMigration on an existing channel or chat, you can continue importing messages by using the startMigration API.
  • 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