Microsoft Teams

Put Microsoft Teams in a flow: post a new Shopify order in the Sales channel with an @mention of whoever handles it, answer in a thread, tell someone by direct message that their request was approved, read the latest messages of a channel for an AI Node to summarize, or keep one status message up to date — with the action node — and fire a flow on every new message in a channel, a chat or all your chats with the trigger. The action node can also be handed to an AI Node as an AI toolkit, for a support agent that lives in Teams.

ℹMessages go out as you. Everything the node does, it does as the person whose account is connected: posts and replies show their name and picture, the way they would if they had typed them. Microsoft only lets apps post as themselves for data migrations, so there is no “bot” sender — connect a dedicated account (say, alerts@yourcompany.com) if the messages shouldn't come from a person.

Connect Microsoft Teams

Click Connect Microsoft Teams — in the node's credential picker or in Settings → Credentials — and sign in with a work or school Microsoft account that has Teams. One credential is one account, with every team and chat it is in.

  • Work or school accounts only. Microsoft offers Teams to apps only for organization accounts: a personal account (outlook.com, hotmail.com, live.com) and the free Teams aren't supported. Microsoft's sign-in screen already turns a personal account away; if one gets through, nothing is saved and the window says Microsoft Teams needs a work or school account.
  • With a Teams license. An account of your organization without Teams connects, but has no teams or chats to show: the team list says This account is not in any team, or has no Teams license.

The first time, an administrator approves it

Microsoft asks for nine permissions, and three of them — reading channel messages, editing and deleting them, and creating channels — can only be granted by an administrator of your Microsoft 365 organization. So the first connection in each organization has to be made by an admin:

  1. A Microsoft 365 admin clicks Connect Microsoft Teams and signs in with their admin account.
  2. On Microsoft's screen they tick Consent on behalf of your organization and accept.
  3. From then on anyone in the organization connects with just their sign-in. If the admin doesn't use Teams, they can delete their own credential afterwards — the approval stays.

Until that happens, everybody else sees Need admin approval on Microsoft's screen (with a button to ask for it, if your organization turned that on), and HostWebhook says Your organization's Microsoft 365 admin has to approve this app first.

PermissionWhat it is forAdmin
Team.ReadBasic.AllList the teams the account belongs to, and a team's name to @mention it.no
Channel.ReadBasic.AllList a team's channels, and a channel's name to @mention it.no
ChannelMessage.SendPost and reply in channels, and add or remove reactions there.no
ChannelMessage.Read.AllRead channel messages, their replies and inline images — and the channel trigger.yes
ChannelMessage.ReadWriteEdit and delete channel messages the account sent.yes
Channel.CreateCreate a channel in a team.yes
Chat.ReadThe chat triggers (Microsoft subscribes to chats with this one).no
Chat.ReadWriteEverything else in chats: list, read, send, open a 1:1, react, edit and delete.no
User.ReadBasic.AllTurn an email into a person, for mentions, direct messages and Find people.no

Microsoft also asks to sign you in and read your profile, which is how the credential knows whose account it is. All of them act as the connected person: the node only reaches the teams, channels and chats that person can.

ℹOnly Teams. It is its own connection: the Outlook, Outlook Calendar, OneDrive, Excel and Word credentials don't work here, and this one doesn't reach the mailbox or the files. Each Microsoft 365 service is connected on its own, with its own consent.
  • Revoking. Remove HostWebhook Teams from myapps.microsoft.com (or an admin removes it for everyone in Microsoft Entra), and the credential stops working; Reconnect it from Settings → Credentials.

The action node

Sixteen operations, in five groups. A new node starts with no mode and no operation picked: choose Single operation, then an operation, and its fields appear.

GroupOperationWhat it doesTeams
Teams & channelsList teamsThe teams the account belongs to, with their IDs.reads
Teams & channelsList channelsThe channels of a team, with their IDs.reads
Teams & channelsCreate channelA standard or a private channel in a team.writes
Channel messagesSend channel messageA new post in a channel, with a subject, importance and @mentions.posts
Channel messagesReply in threadA reply under a post of a channel.posts
Channel messagesList channel messagesThe latest posts of a channel, optionally with their replies.reads
ChatsList chatsThe account's chats — 1:1, group and meeting — with their members.reads
ChatsSend chat messageA message in a chat that already exists.posts
ChatsList chat messagesThe latest messages of a chat, newest first.reads
ChatsSend direct messageA 1:1 message to a person of your organization, by email.posts
Any messageGet messageOne message whole, in a channel or a chat — a post with its replies.reads
Any messageEdit messageChange the text of a message the account sent.edits
Any messageDelete messageDelete a message the account sent, for everyone.deletes
Any messageAdd reactionReact with an emoji.reacts
Any messageRemove reactionTake the account's own emoji reaction off.reacts
PeopleFind peoplePeople of your organization by the start of their name or email.reads

Every text field takes a template: {{payload.threadId}} to answer the message that fired the Microsoft Teams trigger, {{payload.email}} from a form.

⚠The operations that post, edit, delete or react reach real people on every run — Run test included: an @mention notifies, an urgent message keeps ringing. Point the first tests at a channel or a chat of your own.

Picking a team, a channel or a chat

Team, Channel and Chat are picked from the connected account's own lists, each with Refresh next to its label:

  • Team — the teams the account is in; archived ones last, marked Archived.
  • Channel — unlocks once a team is picked, and empties when you pick another team. General comes first and private channels are marked Private. Private and shared channels the account isn't a member of don't show.
  • Chat — the account's 1:1, group and meeting chats, the most recent first, with a hint like Group chat · 5 people.

To take a value from the flow instead, choose Type an ID or a template under the list. Changing the credential empties the team, channel, chat and mentions — they belong to the other account.

Writing a message

  • Message — what to post, up to 28,000 characters. An empty one is refused with The message is empty (content).
  • Format — html (the default when left empty) or text. HTML takes the usual tags: <b>, <i>, <a href>, <ul>, <br>…
  • Subject — the title of a channel post (Send channel message only).
  • Importance — normal (the default), high or urgent. In a chat, an urgent message keeps notifying the recipient.

@mentions

Two ways to @mention a person, in any operation that posts except Send direct message:

  • Mention — emails, comma-separated, or picked from the people of the account's recent chats (type any other email under the list). They go at the start of the message, before the text.
  • <at>ana@yourcompany.com</at> inside the Message — the mention goes at that spot, with the person's name: “Thanks, @Ana García — it's shipped.” A person written both ways is mentioned once, where the <at> is.
  • Mention the channel and Mention the team — in a channel, @mention everyone in it, at the very start.

Up to 20 people per message. Each email has to be a person of your organization: an address that isn't an email fails before anything is sent, with “x” is not an email address., and one Microsoft doesn't know with “x” is not a person in your organization. A message in text format with mentions is sent as HTML — your text as it is, line breaks kept — because that is the only way Teams takes a mention.

Posts, replies and the thread ID

In a channel, a post starts a thread and replies go under it. Two IDs matter, and the trigger and every operation return both:

  • id — the message itself.
  • threadId — the post of its thread: the same as id for a post, the post it answers for a reply.

Reply in thread asks for the post — {{payload.threadId}} answers in the thread of whatever message fired the trigger, post or reply. Given the ID of a reply, Microsoft refuses it, and the node says Reply to the post (threadId), not to another reply.

The Any message operations first ask Where — channel or chat, with no default — and then show the team, channel and Thread ID, or the chat. Fill Thread ID only when the message is a reply in a channel: the ID of its post (replyToId in the payload). Leave it empty for a post or a chat message. Chats have no threads.

Direct messages

Send direct message takes the email of a person of your organization in To and opens your 1:1 chat with them — or reuses it, if you already have one — and posts there. It returns the message, the chat's ID in chatId (for Send chat message later) and who it went to in to.

  • A guest of your organization works too — HostWebhook opens the chat with them as a guest.
  • Yourself: You cannot send a direct message to yourself.
  • Someone outside the organization: “x” is not a person in your organization. Teams chats with other organizations aren't reachable from here.

A Teams message doesn't carry its sender's email — from.email is usually empty — so to answer whoever wrote, reply in the thread or in the same chat ({{payload.chatId}}) rather than by direct message. Find people turns a name into an email.

Reading messages

  • List channel messages — the latest posts, the thread with the most recent activity first (that is how Microsoft orders them). With Include replies, each post comes with up to 200 replies.
  • List chat messages — newest first. With Changed after (an ISO date-time, like 2026-10-05T09:00:00Z or {{payload.createdAt}}), only messages sent, edited or reacted to after it (Microsoft's last-modified time), most recently changed first.
  • List chats — each chat with its name: its topic or, without one, the names of the other people in it. Chat type narrows it to oneOnOne, group or meeting; empty, all of them.
  • Get message — one message whole; a channel post with its replies, with Include replies.

The lists return count and hasMore, and leave out system events (“Ana added Sam to the team”) and deleted messages.

Images and files. Images pasted into a message are counted in imageCount; turn on Save inline images in Get message and they come as files in images[]._file for the next node — up to 10 images and 10 MB in all; the ones that don't fit are listed in skipped with the reason. Files attached to a message live in SharePoint: they come as references in attachments (name and link), not downloaded.

What a message looks like

Every operation that returns a message — and the trigger — returns this same shape, so a flow reads {{payload.text}} the same way from any of them. The one exception is Edit message, which wraps it: { updated: true, message: {…} }, so after an edit read {{payload.message.id}} and {{payload.message.text}}:

{
  "id": "1759675200000",
  "threadId": "1759675080000",
  "replyToId": "1759675080000",
  "isReply": true,
  "kind": "channel",
  "teamId": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b",
  "teamName": "Sales",
  "channelId": "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2",
  "channelName": "Orders",
  "chatId": null,
  "chatTopic": null,
  "chatType": null,
  "from": { "id": "8ea0e38b-…", "name": "Ana García", "email": null, "kind": "user" },
  "text": "@Sam can you check order #1042?",
  "html": "<p><at id=\"0\">Sam</at> can you check order #1042?</p>",
  "contentType": "html",
  "subject": null,
  "importance": "normal",
  "createdAt": "2026-10-05T14:40:00.000Z",
  "editedAt": null,
  "deletedAt": null,
  "mentions": [{ "name": "Sam", "kind": "user", "id": "5c3f…" }],
  "attachments": [],
  "imageCount": 0,
  "reactions": [{ "reaction": "👍", "userId": "8ea0e38b-…" }],
  "messageType": "message",
  "webUrl": "https://teams.microsoft.com/l/message/19%3A4a95…/1759675200000"
}

text is the message as plain text — mentions as @Name, paragraphs as line breaks — and html the original when it was HTML. Times are in UTC, as Microsoft gives them. A chat message has kind: "chat", its chatId, chatTopic and chatType, and no team or channel.

Editing, deleting and reactions

  • Edit message and Delete message work on messages the connected account sent; on anyone else's, Teams refuses and the node says Teams only lets you edit messages the connected account sent. Editing replaces the text, and an edit can't add or change @mentions — a <at>email</at> in an edit is refused; post a new message to mention someone. Deleting is for everyone — the message shows as deleted in Teams.
  • Add reaction takes the emoji character itself — 👍 ❤️ 😂 ✅ — not a name like :thumbsup: (Use the emoji character itself, like 👍.). Remove reaction takes off the connected account's own reaction, nobody else's — handy to mark a message ⏳ while a flow works on it and swap it for ✅ when it is done.
  • Status messages that change — post once with Send channel message, then Edit message with its id: “Order #123: packed” becomes “Order #123: shipped”. A later edit after that one takes the id from {{payload.message.id}}.

Creating channels

Create channel makes a standard channel (the default), which every member of the team sees, or a private one, with the connected account as its owner. The name is up to 50 characters and can't repeat one of the team's; Microsoft's answer is returned as it is. Shared channels aren't offered.

Finding people

Find people looks for people of your organization whose name or email starts with what you write in Search, and returns their id, name and email — the email is what Mention and Send direct message take.


AI toolkit mode

Pick AI toolkit as the node's Mode and it turns into sixteen tools that an AI Node — or an MCP client, through one of your MCP servers — calls by name: “summarize what was said in #support today”, “answer Ana in the thread and react ✅”, “tell Sam by direct message that the report is ready”.

ToolArgumentsStarts
list_teams—available
list_teams_channelsteam_idavailable
create_teams_channelteam_id · name · description? · membership_type?blocked
send_teams_channel_messageteam_id · channel_id · content · content_type? · subject? · importance? · mentions? · mention_channel? · mention_team?available
reply_to_teams_messageteam_id · channel_id · message_id · content · content_type? · importance? · mentions? · mention_channel? · mention_team?available
list_teams_channel_messagesteam_id · channel_id · max_results? · include_replies?available
list_teams_chatschat_type? · max_results?available
send_teams_chat_messagechat_id · content · content_type? · importance? · mentions?available
list_teams_chat_messageschat_id · max_results? · since?available
send_teams_direct_messageuser_email · content · content_type? · importance?available
get_teams_messagewhere? · team_id? · channel_id? · chat_id? · message_id · reply_to_id? · include_replies?available
update_teams_messagewhere? · team_id? · channel_id? · chat_id? · message_id · reply_to_id? · content · content_type?available
delete_teams_messagewhere? · team_id? · channel_id? · chat_id? · message_id · reply_to_id?blocked
add_teams_reactionwhere? · team_id? · channel_id? · chat_id? · message_id · reply_to_id? · reactionavailable
remove_teams_reactionwhere? · team_id? · channel_id? · chat_id? · message_id · reply_to_id? · reactionavailable
find_teams_userssearch · max_results?available

The model gets the IDs from the list tools — list_teams, then list_teams_channels — and the emails from find_teams_users. mentions is a comma-separated list of emails. In the tools for any message, where can be left out: with a chat_id it is a chat, otherwise a channel. The model's arguments are used as written: a {{…}} in them is not filled in. Saving inline images isn't a tool option — the model can't open files.

What you control

  • Deleting a message and creating a channel start blocked. delete_teams_message deletes for everyone, and create_teams_channel makes something the whole team sees. Unblock them in the node's tool list if the agent should have them. Any other tool can be blocked the same way — the sending ones, for an agent that should only read. Editing a message and removing the agent's own reaction start available.
  • Teams the agent can use. Empty, every team of the account. Pick some and the channel tools refuse any other team — This node only lets the agent use these teams: Sales, Support. — and list_teams only lists those. Chats have no such list: to keep an agent out of chats, block send_teams_chat_message, send_teams_direct_message, the chat reads and the any-message tools (get_teams_message, update_teams_message, delete_teams_message, add_teams_reaction, remove_teams_reaction), which reach a chat when given a chat_id — blocking those also blocks them in channels.
  • Characters per call sent to the model. 20,000 by default. Lists are capped too: 50 messages or chats per call, 25 people.

Testing a tool

⚠Only a tool call picks the tool. In AI toolkit mode, only an AI Node, an MCP client or a voice agent chooses which tool the node runs. Run Test, a flow or a webhook run the operation saved on the node: an operation in their payload that names another tool is refused.
✦To try a tool, call it from an AI Node or from an MCP client. Its arguments look like this:
jsonA tool call
{ "operation": "list_teams_channel_messages", "team_id": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b", "channel_id": "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2", "max_results": 5 }
⚠A node in toolkit mode is not part of the pipeline. Events arriving through connections made before you switched are refused — the node only runs the tool it is asked for.

The trigger

Pick a Microsoft Teams credential and answer three questions — none comes answered, and Activate stays off until all three are:

  • Watch — A channel (pick the team, then the channel), One chat (pick it), or All my chats — every chat the account is in, including the ones that start later.
  • Fires on — New messages, or New and edited messages. In a channel, a reply is a new message too.
  • Messages sent from the connected account — Skip them or Include them. Skip is the one to pick for a flow that posts where it listens — an agent that answers in the same channel would otherwise fire itself with its own answer.

Optionally:

  • Only messages containing some text (upper or lower case, looked for in the plain text, up to 255 characters).
  • Only when the connected account is @mentioned — for an assistant people call by name.
  • Only new posts, not replies — channels only.

How it fires

Activating subscribes with Microsoft. When a message arrives, Microsoft sends HostWebhook a notice — usually within ten seconds, at most a minute — with a secret that belongs to this trigger and without the message itself; HostWebhook checks the secret, then reads the message with the trigger's own credential, applies your filters and fires the flow.

  • Once per message, even when Microsoft sends the notice twice. With New and edited messages, each edit fires once more, with event: "edited".
  • Reactions don't fire it, nor do deleted messages or system events (“Ana added Sam”).
  • With New messages, an edit is ignored without even reading it.

Two triggers on the same channel or chat

Microsoft keeps one subscription per app and channel or chat. So the second trigger you activate on a channel — yours or a teammate's, with the same answers or different ones — joins the subscription of the first instead of making its own. Each still reads with its own credential and applies its own questions and filters: one can fire on edits and the other not.

  • Before joining, HostWebhook checks that the second account can read that channel or chat; if it can't, activating fails with Microsoft's answer.
  • Deactivating the first trigger hands the subscription to the others, which keep firing.
  • If the subscription belongs to a connection HostWebhook can't see — a trigger deleted while Microsoft was unreachable — activating says Microsoft already has a subscription for this channel or chat from another connection that HostWebhook cannot see or remove. It expires within three days; or connect the same Microsoft account and activate again.
ℹMicrosoft's subscriptions to Teams messages last at most three days. HostWebhook asks for just under that and renews them on its own. If Microsoft removes one, reports that notices were missed, or the subscription ran out, HostWebhook subscribes again and delivers what arrived in between — up to 200 messages, oldest first, without repeating any. In a channel, a reply in an old thread with more than 200 replies can be missed. Deactivating deletes the subscription.

What the trigger sends downstream

The message, in the same shape the action node returns (see What a message looks like), with event and fromMe in front (plus service: "teams" and a _meta block, like the other Microsoft triggers):

{
  "event": "created",
  "fromMe": false,
  "id": "1759675200000",
  "threadId": "1759675080000",
  "isReply": true,
  "kind": "channel",
  "teamName": "Sales",
  "channelName": "Orders",
  "from": { "id": "8ea0e38b-…", "name": "Ana García", "email": null, "kind": "user" },
  "text": "@Sam can you check order #1042?",
  "createdAt": "2026-10-05T14:40:00.000Z",
  "editedAt": null,
  …
}
  • event — created or edited.
  • fromMe — whether the connected account sent it (only ever true with Include them).

Answer it in its thread with Reply in thread and {{payload.threadId}}, or in its chat with Send chat message and {{payload.chatId}}; react to it with {{payload.id}}.

Trying it out

The trigger's Test push reads the latest real messages — of the channel (posts and replies), of the chat, or the last message of your most recent chats — applies your filters, and shows them exactly as a delivery will arrive, without running the flow. To see a real one, activate the trigger and have someone write there: with Skip them, your own messages won't fire it.


Good to know

Which accounts and teams

  • Work or school accounts with Teams, approved once by an admin of the organization (see above). Personal accounts and the free Teams can't be connected.
  • Your own organization's teams. Teams of another organization where the account is a guest, and channels shared from another organization, aren't reached: the connection is to the account's home organization.
  • Approving it in your organization doesn't approve it in another. Each organization's admin approves it once.

Sizes and counts

WhatUp to
A message (Message)28,000 characters
People @mentioned in one message20
List channel messages, List chats, List chat messages — How many1 to 50; 20 by default
Find people — How many1 to 25; 20 by default
Replies that come with a post (Include replies)200 per post
Members listed per chat (List chats)25
Get message — Save inline images10 images and 10 MB in all, per run
A channel name (Create channel)50 characters
Trigger — Only messages containing255 characters
Trigger — messages caught up after a gap200
AI toolkit — characters per call sent to the model20,000 by default

What it doesn't do

  • Send files or images. In Teams a file is a SharePoint file of the channel. Upload it with the OneDrive node, share a link, and post the link.
  • Adaptive cards, buttons and “send and wait” — messages are text or HTML.
  • Post as a bot — see Messages go out as you.
  • Start group chats — Send direct message opens 1:1 chats; group chats are written to once they exist.
  • Mention tags, and delete channels or teams.

When it fails

  • Forbidden (403). Microsoft's message, and — when it can be about permissions — If your organization has not approved HostWebhook Teams yet, a Microsoft 365 admin has to connect it once and accept for the whole organization; then reconnect this credential.
  • Not found (404). Microsoft Teams could not find it — a wrong or deleted ID, or a team or private channel the connected account isn't a member of.
  • Before calling Microsoft, the node refuses what it can tell is wrong: an empty message, more than 20 mentions, a channel name over 50 characters, an address that isn't an email, an emoji written as a name, a channel operation without its team and channel or a chat one without its chat.
  • Reconnect — the account revoked HostWebhook Teams or the sign-in expired: reconnect the credential in Settings → Credentials. A credential of another Microsoft service is refused with This is not a Microsoft Teams credential.
  • Busy or throttled. Microsoft limits how fast an app can post in a team. When it answers that it is busy, the node waits the time it asks for (up to ten seconds) and tries again; if Microsoft is still busy after the retries, it gives up with Microsoft's message.
  • No confirmation. If Microsoft doesn't answer a post or a new channel (a timeout or a 502/504), the node fails with Microsoft Teams didn't confirm it — it may have gone through; check Teams before running it again. It does not retry on its own, so the message is never posted twice.