diff --git a/content/docs/platform/integrations/chat/(providers)/ms-teams.mdx b/content/docs/platform/integrations/chat/(providers)/ms-teams.mdx
index 63969eb4d..c31ff2723 100644
--- a/content/docs/platform/integrations/chat/(providers)/ms-teams.mdx
+++ b/content/docs/platform/integrations/chat/(providers)/ms-teams.mdx
@@ -3,68 +3,398 @@ title: 'MS Teams'
description: 'Learn about how to use MS Teams provider for chat notifications'
---
-import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
+The Novu Microsoft Teams integration enables you to send notifications to Teams channels and direct messages (DMs) across different customer workspaces using a single multi-tenant bot.
-MS Teams does not need any `API Key` or `Client ID` to send notifications. Our current implementation is based on the [Incoming Webhook URL](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=newteams%2Cjavascript). It is a URL that you can use to send messages to a specific channel. This URL needs to be stored on the subscriber entity
+You create and host a Microsoft Teams bot in your Azure environment, and your customers then approve the app (via Admin Consent) and install it in their Teams tenants.
-Similar to [Discord](/platform/integrations/chat/discord), the credential for this provider needs to be stored in the [subscriber entity](/api-reference/subscribers/update-provider-credentials).
+Once a customer connects their workspace, Novu establishes a secure channel connection using your bot's credentials. You then map specific destinations, whether the destinations involve public channels or individual users to channel endpoints, allowing Novu to route notifications dynamically to the correct tenant and conversation context.
-## Creating incoming webhook URL
+## Azure and Teams configuration
-Checkout step by step instructions on microsoft team's documentation on how to [create an incoming webhook url](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=newteams%2Cjavascript).
+Before you can configure Novu, you must create the infrastructure that hosts your bot. This involves two distinct portals:
+- **Azure portal**: To create the identity (App Registration) and infrastructure (Bot Service).
+- **Teams Developer Portal**: To create the app package that your customers can install.
-
+### Create the app identity (Azure AD)
-## Storing webhook url on subscriber entity
+First, create a multi-tenant identity for your bot.
-The URL generated above will be the target channel of a subscriber that you want to integrate with. To make this connection, you have to:
+1. Log in to the Azure Portal.
+2. In the menu, click **Microsoft Entra ID** (formerly Azure Active Directory).
+3. In the Manage section, click **App registrations**.
+4. To create an app, click **New registration**.
+ 
+5. Fill in the form:
+ - **Name**: Enter any name of your choice.
+ - **Supported account types**: Select **Accounts in any organizational directory (Any Microsoft Entra ID directory - Multitenant)**.
+ 
+6. Click **Register**.
+ 
+7. After creating the app, note the Application (client) ID and Directory (tenant) ID. You need these values to configure Microsoft Teams in Novu.
-1. Copy the URL that you generated above
-2. Update the subscriber credentials with this URL using the MS Teams provider id. You can do this step by using the `@novu/api` library, as shown below:
+### Configure client secret
-
-
-```typescript
+1. On your new app's overview page, click **Certificates & secrets**.
+2. Click **New client secret**.
+
+3. Add a description.
+4. Set an expiry date.
+5. Click **Add**.
+
+6. Copy the value. This value becomes your `BOT_APP_SECRET`, and you’ll paste it into Novu. You can view the secret only once right after you create it, so save it before you leave the page.
+
+### Add Novu’s redirect URI
+
+After your customers go through the administrator consent page, Microsoft needs to know where to send them back after they accept.
+
+1. Click **Authentication (Preview)**.
+2. Click **Add Redirect URI**.
+3. In the menu that appears, click **Web**.
+4. In the **Redirect URI** field, set the redirect URI to the Novu OAuth callback URL:
+ - US region
+ ```bash
+ https://api.novu.co/v1/integrations/chat/oauth/callback
+ ```
+ - EU region
+ ```bash
+ https://eu.api.novu.co/v1/integrations/chat/oauth/callback
+ ```
+ 
+5. Click **Configure**.
+
+### Add Microsoft Graph app permissions
+
+These permissions let your app list teams and channels and decide where to send messages.
+
+1. Click **API permissions**.
+2. Click **Add a permission**.
+3. Click **Microsoft Graph**.
+ 
+4. Click **Application permissions**.
+5. Search for and select the following permissions:
+ - `Team.ReadBasic.All`
+ - `Channel.ReadBasic.All`
+ - `AppCatalog.Read.All`
+ - `TeamsAppInstallation.ReadWriteSelfForTeam.All` (optional, for automation)
+ - `TeamsAppInstallation.ReadWriteSelfForUser.All` (optional, for automation)
+5. Click **Add permissions**.
+
+### Create an Azure Bot resource
+
+Now you register your bot with the Azure AI Bot Service and link it to the app registration that you just created.
+
+1. In the Azure portal menu, click **Create a resource**.
+2. Search for “Azure Bot”, and then click the Azure Bot resource.
+ 
+3. Click **Create**.
+4. Fill in the basics:
+ - **Bot handle**: The unique display name in Azure.
+ - **Subscription**: Select the Azure subscription.
+ - **Resource group**: A collection of resources that share the same lifecycle, permissions, and policies, you can either select or create one.
+ - **Data residency**: Specify an option for data residency, either global or regional.
+5. Under **Microsoft App ID**:
+ - **Type of app**: Select Single-tenant app registration.
+ - **Creation type**: Choose “Use existing app registration” and use app IDs [you created earlier](/platform/integrations/chat/ms-teams#create-the-app-identity-azure-ad):
+ - **App ID**: Replace with the Application (client) ID.
+ - **App tenant ID**: Replace with the Directory (tenant) ID.
+ 
+6. Click **Review + create**.
+7. Click **Create**.
+
+### Enable the Microsoft Teams channel
+
+This connects your bot resource to Teams and lets your Teams app install cleanly.
+
+1. Once the deployment finishes, click **Go to resource**.
+ 
+2. Click **Settings**.
+3. Click **Channels**.
+4. In the available channelssection, click **Microsoft Teams**.
+5. In the menu that appears, accept the terms of services.
+6. In the **Messaging** section, choose the appropriate environment, typically **Microsoft Teams Commercial**.
+7. Click **Apply**.
+
+### Create a Teams app
+
+Now you create the Teams “wrapper” around your app registration and bot.
+1. Open the Teams Developer Portal.
+2. Click **Apps**.
+3. Click **+ New app** and then enter a name.
+4. Click **Add**.
+5. In the basic information page, fill in the required fields.
+6. Select **App feature**.
+6. Add a **Bot** and then select **Enter a bot ID**.
+7. Set the **Bot ID** to your `BOT_APP_ID`, the same App ID you used for the Azure Bot.
+8. Enable “What can your bot do?” to “Only send notification” as the least option.
+9. Enable scopes based on your use case:
+ - `team` for channel messages
+ - `personal` for DMs
+
+You don’t need to edit the JSON yourself. The developer portal generates and checks it for you.
+
+### Publish the Teams app
+
+Next, publish the app to a Teams store, if you want the app publicly available in the store. Publish to org if you want it accessible only inside your organization teams.
+
+Refer to the Microsoft Teams documentation to learn how to:
+ - Publish to your org.
+ - Publish to the Teams store.
+
+## Configure the Teams (Bot) integration in Novu
+
+Now that you’ve configured your Azure Bot, provide Novu with the credentials to integrate it.
+
+1. Log in to the Novu dashboard.
+2. In the sidebar, click Integrations Store.
+3. Click **Connect Provider**.
+4. Select **Chat** and click **MSTeams**.
+5. Enter the credentials you saved from the Azure Portal:
+ - **Client ID**: Enter your `BOT_APP_ID`.
+ - **Client Secret**: Enter your `BOT_APP_SECRET`.
+ - **App Tenant ID**: Enter your `APP_TENANT_ID`. This value identifies the tenant where you registered the app.
+ - **Redirect URL** (Optional): If you want to control where your users land after they grant administrator consent, then enter that URL here. If you leave it empty, then the consent window closes automatically.
+ 
+6. Click **Create Integration**.
+
+Novu is now authenticated to act as your bot, but it still can't send messages because no customers have installed it.
+
+## Let your customers connect their tenant
+
+Each of your customers has their own Microsoft 365 tenant. Before you can send them messages, they must grant your app a one time administrator consent. This authorizes your bot to act within their environment.
+
+### Generate a Connect Teams URL
+
+On your backend, use the Novu SDK to generate the authorization URL. This URL is specific to the customer's tenant context in your system.
+
+```tsx
import { Novu } from '@novu/api';
-import { ChatOrPushProviderEnum } from "@novu/api/models/components";
-const novu = new Novu({
- secretKey: "",
- // Use serverURL for EU region
- // serverURL: "https://eu.api.novu.co",
+const novu = new Novu({ secretKey: "", });
+
+const url = await novu.integrations.generateChatOAuthUrl({
+ integrationIdentifier: 'ms-teams-bot', // The identifier used for that integration on Novu
+ subscriberId: 'customer-admin-id', // (optional)
+ context: { tenant: 'acme-corp' }, // (optional)
});
+```
+
+Novu returns a URL pointing to Microsoft's administrator consent endpoint. This URL already includes your Client ID, Redirect URI, and the necessary Graph scopes.
+
+### Show it in your UI
+
+In your frontend app, bind this URL to a button:
+
+```
+// On "Connect Microsoft Teams" button click:
+window.open(url, '_blank');
+```
+
+### What the customer administrator does
+
+Steps the customer administrator would take:
+
+1. A Teams/Microsoft 365 Admin from your customer's organization logs into your product.
+2. They click your **Connect Microsoft Teams** button.
+3. They see a Microsoft consent page listing the permissions.
+4. They click **Accept**.
+
+Once the user completes this step, Microsoft redirects the user back to Novu. Novu captures the customer's tenant ID and automatically creates a Teams connection for that specific tenant context. You don't need to handle the callback yourself.
+
+### Customer installs your app in their Teams
+
+Granting Admin consent in the previous step only authorizes your bot to exist in the customer's tenant. It doesn't automatically add the bot to any specific teams or chats.
+
+For the bot to send messages, install it in the specific context where notifications should appear:
+
+- **For channel messages**: Install the app in the specific Team.
+- **For direct messages**: Install the app for the specific user in their personal scope.
+
+The customer’s administrator can install your app from the Teams app store or their org catalog, depending on how you published. If you requested the `TeamsAppInstallation.ReadWriteSelfForTeam.All` permission, your backend can programmatically install the app into a specific Team using the Microsoft Graph API.
+
+## Tell Novu where to send the messages
+
+Your customer decides where notifications should land and gives you the right IDs and then your backend registers them as Channel Endpoints in Novu.
+
+You can choose between two destination types:
+ - **Channels**: Send a message to a specific channel within a Team.
+ - **Users**: Send a direct message to a specific user.
+
+### Sending message to channels
+
+To send a notification to a specific channel, you must discover the Team ID and Channel ID from Microsoft, and then register them in Novu.
+
+#### Find the Team and Channel IDs (Microsoft Graph)
+
+You can discover these IDs using the Microsoft Graph API. This requires an App-Only Token (Client credentials) scoped to the customer's tenant.
+
+1. Get a Graph access token:
+
+```bash
+POST https://login.microsoftonline.com/{SUBSCRIBER_TENANT_ID}/oauth2/v2.0/token
+Content-Type: application/x-www-form-urlencoded
-await novu.subscribers.credentials.update(
- {
- providerId: ChatOrPushProviderEnum.MsTeams,
- credentials: {
- webhookUrl: "",
- },
- integrationIdentifier: "msteams-MnGLxp8uy",
+client_id={BOT_APP_ID}
+&client_secret={BOT_APP_SECRET}
+&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
+&grant_type=client_credentials
+```
+
+The `SUBSCRIBER_TENANT_ID` represents the customer's tenant ID, which Novu stored on the `ChannelConnection` object after completing the Admin Consent flow.
+
+```bash
+GET /v1/channel-connections
+{
+ "identifier": "chconn-eeybt4",
+ "integrationIdentifier": "msteams",
+ "providerId": "msteams",
+ "channel": "chat",
+ "subscriberId": "689c4a87c5bdaa96aaef0cfd",
+ "workspace": {
+ "id": "e6633b86-ef94-4416-863f-f0f409700ca0" // the customer's tenant workspace ID
+ },
+ "auth": {
+ "accessToken": "app-only"
},
- "subscriberId"
-);
+}
+```
+
+2. List Teams:
+
+```bash
+GET https://graph.microsoft.com/v1.0/teams
+Authorization: Bearer {ACCESS_TOKEN}
+```
+
+3. List channels in a Team:
+
+```bash
+GET https://graph.microsoft.com/v1.0/teams/{TEAM_ID}/channels
+Authorization: Bearer {ACCESS_TOKEN}
```
-
-
+
+#### Register the channel endpoint (Novu)
+
+Once you have the IDs, create an `ms_teams_channel` endpoint in Novu. This maps a subscriber to that specific channel.
+
+```bash
+POST /v1/channel-endpoints
+Authorization: ApiKey {CUSTOMER_API_KEY}
+Content-Type: application/json
+
+{
+ "identifier": "msteams-main-notifications",
+ "integrationIdentifier": "ms-teams-bot-1",
+ "providerId": "msteams",
+ "channel": "chat",
+
+ "subscriberId": "workspace_abc",
+ "connectionIdentifier": "msteams-tenant-subscriberX",
+
+ "type": "ms_teams_channel",
+ "endpoint": {
+ "teamId": "TEAM_ID",
+ "channelId": "CHANNEL_ID"
+ },
+}
+```
+
+Novu stores this as `ChannelEndpoint<'ms_teams_channel'>`. You can later target it from workflows via `subscriberId` + `context`.
+
+### Send a direct message to a user
+
+To send a direct message (DM), you need the user's Teams User ID before registering the user endpoint in Novu.
+
+#### Find the user ID (Bot framework)
+
+Use the Bot framework API to inspect the roster of the Team where you installed the bot.
+
+1. Install the bot in at least one Team that includes the target user.
+2. Get a Bot Framework token:
+ ```bash
+ POST https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
+ Content-Type: application/x-www-form-urlencoded
+
+ grant_type=client_credentials&
+ client_id={BOT_APP_ID}&
+ client_secret={BOT_APP_SECRET}&
+ scope=https%3A%2F%2Fapi.botframework.com%2F.default
+ ```
+3. Call the roster API for that Team, using the Team’s `19:...@thread.tacv2` id as `{TEAM_CONVERSATION_ID}`:
+ ```bash
+ GET https://smba.trafficmanager.net/teams/v3/conversations/{TEAM_CONVERSATION_ID}/members
+ Authorization: Bearer {BOT_ACCESS_TOKEN}
+ ```
+
+From the returned members, take the member’s `id`; this value represents the Teams user ID (`29:...`) you’ll use as `userId`.
+
+#### Register the user endpoint (Novu)
+
+Once you have the IDs, create the endpoint in Novu using the `ms_teams_user` type.
+
```bash
-curl -L -X PUT 'https://api.novu.co/v1/subscribers//credentials' \
--H 'Content-Type: application/json' \
--H 'Accept: application/json' \
--H 'Authorization: ApiKey ' \
--d '{
+POST /v1/channel-endpoints
+Authorization: ApiKey {CUSTOMER_API_KEY}
+Content-Type: application/json
+
+{
+ "identifier": "msteams-user-alice",
+ "integrationIdentifier": "ms-teams-bot-1",
"providerId": "msteams",
- "credentials": {
- "webhookUrl": ""
+ "channel": "chat",
+
+ "subscriberId": "user_123",
+ "connectionIdentifier": "msteams-tenant-subscriberX",
+
+ "type": "ms_teams_user",
+ "endpoint": {
+ "userId": "29:1GcS4EyB_oSI8A88XmWB..."
},
- "integrationIdentifier": "msteams-MnGLxp8uy"
-}'
+
+ "contextKeys": []
+}
```
-
-
-Checkout the [API reference](/api-reference/subscribers/update-provider-credentials) for more details.
+Novu stores this as `ChannelEndpoint<'ms_teams_user'>`. From here, any workflow that resolves to this endpoint can send a DM from your bot to that user.
+
+## Workflows for Teams (Webhook-style)
+
+If you don't need a full Bot identity or Direct Message capabilities, then you can support a simplified, channel-only integration using Workflows for Microsoft Teams.
+
+This approach relies on a unique Webhook URL generated by the Teams client. It requires no Azure app registration and no administrator consent.
+
+### User generates the webhook URL (Teams client)
+
+The setup begins inside the Microsoft Teams app. Instruct your users to follow these steps:
+
+1. In Microsoft Teams, go to **Apps** in the sidebar.
+2. Search for and open **Workflows**.
+3. Click **Create new flow**, either from blank or template.
+4. Choose a trigger, such as “When a Teams webhook request is received”.
+5. Add an action to post a message into a specific channel.
+6. Save the workflow.
+7. Once created, the workflow generates a unique URL. The user must copy this URL.
+
+### Register the webhook endpoint (Novu)
+
+Unlike the Bot integration, you don't use `ms_teams_channel` here. Instead, you treat this as a generic webhook endpoint. Your app should provide a form where the user can paste the URL they generated in the previous step.
+
+```bash
+await novu.channelEndpoints.create({
+ type: 'webhook',
+ identifier: 'teams-workflow-alerts',
+ integrationIdentifier: 'ms-teams-workflow',
+ subscriberId: 'customer-account-id',
+ context: { tenant: 'acme' },
+ endpoint: {
+ url: 'https://prod-00.westeurope.logic.azure.com:443/workflows/...' // workflow URL
+ },
+});
+```
+
+### Sending the notification
+
+When you trigger a workflow that targets this subscriber:
-- `subscriberId` is a custom identifier used when identifying your users within the Novu platform.
-- `providerId` is a unique provider identifier. We recommend using our ChatOrPushProviderEnum to specify the provider.
-- The third parameter is the credentials object, in this case, we use the `webhookUrl` property to specify the MS Teams channel webhook URL or by calling the `Update Subscriber Credentials` endpoint on Novu API. Check endpoint details [here](/api-reference/subscribers/update-provider-credentials).
+1. Novu sends a standard HTTP POST payload to the Teams Workflow URL.
+2. Workflows for Teams receives the payload.
+3. The Workflow runs and posts the message content into the configured channel.
\ No newline at end of file
diff --git a/public/images/channels-and-providers/chat/msteams/add-permissions.png b/public/images/channels-and-providers/chat/msteams/add-permissions.png
new file mode 100644
index 000000000..2bcde3d64
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/add-permissions.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/add-redirect-uri.png b/public/images/channels-and-providers/chat/msteams/add-redirect-uri.png
new file mode 100644
index 000000000..4d109a174
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/add-redirect-uri.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/app-registrations.png b/public/images/channels-and-providers/chat/msteams/app-registrations.png
new file mode 100644
index 000000000..8da6e54b0
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/app-registrations.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/azure-bot.png b/public/images/channels-and-providers/chat/msteams/azure-bot.png
new file mode 100644
index 000000000..dba974490
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/azure-bot.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/certificates-and-secret.png b/public/images/channels-and-providers/chat/msteams/certificates-and-secret.png
new file mode 100644
index 000000000..9727da2ca
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/certificates-and-secret.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/client-secret.png b/public/images/channels-and-providers/chat/msteams/client-secret.png
new file mode 100644
index 000000000..ee7db9528
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/client-secret.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/create-app.png b/public/images/channels-and-providers/chat/msteams/create-app.png
new file mode 100644
index 000000000..0fb03afc4
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/create-app.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/create-azure-bot.png b/public/images/channels-and-providers/chat/msteams/create-azure-bot.png
new file mode 100644
index 000000000..06c99f9d4
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/create-azure-bot.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/create-incoming-webhook.gif b/public/images/channels-and-providers/chat/msteams/create-incoming-webhook.gif
deleted file mode 100644
index 0b1f7efb9..000000000
Binary files a/public/images/channels-and-providers/chat/msteams/create-incoming-webhook.gif and /dev/null differ
diff --git a/public/images/channels-and-providers/chat/msteams/go-to-resource.png b/public/images/channels-and-providers/chat/msteams/go-to-resource.png
new file mode 100644
index 000000000..b645d4904
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/go-to-resource.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/novu-msteams-integration.png b/public/images/channels-and-providers/chat/msteams/novu-msteams-integration.png
new file mode 100644
index 000000000..cd7cb82dd
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/novu-msteams-integration.png differ
diff --git a/public/images/channels-and-providers/chat/msteams/register-application.png b/public/images/channels-and-providers/chat/msteams/register-application.png
new file mode 100644
index 000000000..8d1bfb97d
Binary files /dev/null and b/public/images/channels-and-providers/chat/msteams/register-application.png differ