Microsoft Teams

Send A vs B's experiment, flag, and safety alerts straight into a Microsoft Teams channel. Each one renders as an Adaptive Card, Microsoft's format for rich chat messages. The layout matches the Slack version: same headline, same context, same main button. A team using both chat apps sees the same message either way.

Two ways to connect

Teams has no sign-in flow for incoming notifications. Instead, a channel admin creates a webhook (a URL that A vs B can post messages to) on Microsoft's side, and pastes it into A vs B. There are two ways to get that URL, and A vs B accepts both:

VariantWhen to useLong-term outlook
Power Automate (recommended)The path Microsoft is steering customers toward. Created in the Power Automate portal as "Post a webhook request when an HTTP request is received."First-class support. Microsoft keeps building Power Automate as its long-term workflow tool.
Classic Incoming Webhook (legacy)The original Office 365 connector. Still works in 2026, but Microsoft has announced it will retire the feature, and new tenants may not be able to add new connectors.We keep accepting these URLs so customers who have not switched to Power Automate are not blocked.
Pick one per channel

Each Teams destination in A vs B is one webhook URL bound to one channel. You can run both variants at once, for example one channel on Power Automate and another on the classic connector, while you migrate. That works fine.

  1. In Microsoft Teams, open the channel that should receive A vs B notifications.
  2. Click the + tab at the top of the channel, search for Workflows, and add the workflows app to the channel.
  3. From the workflow templates, choose "Post to a channel when a webhook request is received". Sign in with the Teams account that owns the channel.
  4. On the configuration page, name the workflow (for example "A vs B notifications") and confirm the channel. Save the workflow.
  5. Power Automate then shows the HTTP trigger URL. Copy the full URL. It includes ?api-version=… and &sig=… query parameters that A vs B needs to authenticate against the workflow.
  6. In A vs B, open Organization Settings, then the Integrations tab. Find the Microsoft Teams card.
Organization Settings, Integrations tab: the Microsoft Teams card, before any channel is connected.
  1. Click Add your first Teams channel (or Add Teams channel once you already have one).

Choose Power Automate (recommended), paste the URL, name the destination, and submit.

The Add Microsoft Teams channel form: pick a webhook type, paste the URL, and name the channel.
  1. Choose Power Automate or Classic Incoming Webhook, matching the URL you copied.
  2. Paste the webhook URL. A vs B checks its shape and tells you which type it found.
  3. Name the channel and click Add channel. A vs B sends a test message right away, so you know immediately whether it worked.

Setup: Classic Incoming Webhook (legacy)

  1. In Microsoft Teams, open the channel and choose Connectors from the channel's overflow menu.
  2. Search for Incoming Webhook and click Configure.
  3. Give it a name (for example "A vs B") and optionally upload an icon. Click Create.
  4. Teams shows the webhook URL. Copy the full URL.
  5. In A vs B, open Organization Settings, then the Integrations tab, and click Add Teams channel. Use the same form shown above, choosing Classic Incoming Webhook (legacy) instead.
Deprecation notice

Microsoft announced in 2024 that classic Incoming Webhook connectors are deprecated and will eventually stop accepting new configurations. Plan a migration to Power Automate when your tenant is ready.

Route events to the channel

Connecting a channel does not by itself send you anything. A vs B routes events per project, so you choose which projects notify this channel, and about what.

  1. Open the project, click Settings, then the Notifications tab.
  2. Under Notification routing, find your new Teams destination.
  3. Check the events you want it to receive. Each change saves on its own, per destination.
Project Settings, Notifications tab: turn on the events this project sends to a connected Teams channel.
  1. Find your Teams destination in the Notification routing list.
  2. Check the events this project should send. Each change saves for that destination only.

Repeat for every project that should notify this channel. Skipping this step is the most common reason a newly connected channel goes quiet: the connection test still succeeds, because it posts directly to Teams without touching routing at all.

Events you can route

A vs B fires the same event vocabulary to every destination type: Slack, Teams, Jira, and webhooks. An organization-level keyword gate decides which experiments are worth notifying about. By default, an experiment only fires notifications once its name starts with LIVE or PROD; see notification keywords for the full convention.

  • Experiment lifecycle: launched, paused, resumed, completed, changes published, visual editor changes saved.
  • Analytical: winner declared, daily results digest.
  • Safety: SRM (a red flag that fires when the traffic split does not match what you configured, usually a bug) check failed, guardrail (a metric you do not want to get worse, like page load time) breached, guardrail metric breached, and code errors detected in a variation. These ignore the keyword gate above. Something being wrong is worth knowing regardless of the experiment's name.
  • Feature flag (a setting in your code you can turn on, off, or change without a new deploy): flag published, flag rule activated. Neither is gated by keywords. Flags also mirror the same SRM, guardrail, and daily-digest events as experiments.
  • Exclusion groups (a rule that keeps one visitor out of two conflicting experiments at once): created, updated, deleted.
  • Commerce and background work: import completed, recommendation run completed, dataset version activated, catalog feed sync completed, background job failed.

Message format

Every event renders as one Adaptive Card, in the same order every time:

  • A bold headline.
  • A context row underneath: Project · Environment · Engine.
  • A stat block, for events that carry results.
  • A View in AvsB button that opens the right page.

Winner cards carry a green stripe down the card. SRM and guardrail cards carry a warning stripe, plus a banner reading "Safety alert: keyword gate bypassed", so the team understands why the message fired even though the experiment's name did not start with a keyword.

Daily results digest

Slack's daily digest posts as threaded replies under one parent message. Teams Adaptive Cards do not support threads, so Teams gets one consolidated card instead, with each experiment as its own section.

Teams caps how big that one card can be: 28 KB. If the consolidated card would be too big, A vs B splits it into several cards, each titled "Daily results for {date} (Part {n} of {m})".

Replacing a webhook URL

If the Teams-side webhook URL changes, because the customer rotated it, recreated the connector, or moved from classic to Power Automate, update it in A vs B. Open Organization Settings, then the Integrations tab, find the destination card, and click Replace URL.

Paste the new URL. A vs B checks it, saves it, clears any earlier reason the destination was turned off, and sends a test message. Routes and delivery history stay exactly as they were.

Troubleshooting

My card didn't render in the channel

Open the destination card on the Integrations page and click Send test. A failed test names the problem. If the test succeeds but no card shows up in the channel, the Power Automate flow may be posting to a different channel: check its post step in the Power Automate portal.

My webhook URL stopped working

If Teams returns 404 or 410 to a delivery attempt, A vs B turns the destination off and shows a banner on the card: "Webhook URL is no longer valid. Regenerate on Teams and paste the new URL." Use Replace URL, described above, to fix it.

The daily digest is too long

A long digest splits into several cards automatically, each titled "Daily results for {date} (Part {n} of {m})". To get fewer digest events instead, narrow the routing on the project's Notifications tab so fewer experiments send results-ready events to this destination.

Teams reports "Power Automate misconfigured"

Some misconfigured Power Automate flows return an HTML success page instead of the expected JSON reply. A vs B treats that as a permanent failure and turns the destination off. On the Power Automate side, confirm the HTTP trigger and the channel-post step are both saved. If Power Automate issued a new URL while you were editing, use Replace URL to update it in A vs B.

Audit log entries

Every Teams action is recorded in the audit log, so an admin can reconstruct exactly when and by whom each connection was created, rotated, or tested:

  • NOTIFICATION_DESTINATION_CREATED: a Teams destination is added.
  • NOTIFICATION_DESTINATION_UPDATED: the display name or other descriptive fields change.
  • NOTIFICATION_DESTINATION_DELETED: a destination is removed.
  • TEAMS_DESTINATION_URL_ROTATED: the webhook URL is replaced. The change record redacts secretHash itself (both the old and new values are stored as the literal string (rotated)); only the last four characters of the new hash are kept, in a separate metadata field, so a teammate can confirm which URL is live without anything in the log being enough to reconstruct it.
  • TEAMS_TEST_MESSAGE_SENT: a test message is sent, with whether it succeeded and the HTTP status code Teams returned.
What we do not log

A vs B never logs the full webhook URL. Audit entries carry only the last four characters of its hash, enough to tell two destinations apart, never enough to reconstruct the URL. The URL itself is never returned to the dashboard after you paste it, and it only leaves our servers to post to Teams.

Was this helpful?