Skip to content
CloudOps
Newsletter
All guides
AI for Microsoft Teams By James Joyner IV · · 8 min read

Migrate Your Teams Incoming Webhooks to Workflows Before They Break

Microsoft is retiring Office 365 connector webhooks. Here's how to migrate your DevOps notifications to Workflows without losing adaptive card formatting.

  • #microsoft-teams
  • #workflows
  • #webhooks
  • #power-automate
  • #migration
  • #alerting

If your CI pipeline, monitoring stack, or scripts post to Teams via an “Incoming Webhook” connector URL ending in webhook.office.com, you’re on borrowed time. Microsoft is retiring Office 365 connectors, and those classic webhook URLs are going away. I’ve migrated a few dozen of them, and the good news is it’s mostly mechanical — but there are two real gotchas that bite people.

Here’s the migration playbook.

What’s actually changing

The old model: each channel could expose an “Incoming Webhook” connector with a long-lived office.com URL. You POST a JSON payload (MessageCard or adaptive card) and it appears in the channel. Simple, but built on the deprecated connectors framework.

The new model: Workflows (powered by Power Automate). You create a flow triggered by “When a Teams webhook request is received,” which gives you a new HTTPS URL. You POST your card to that URL, the flow runs, and it posts to the channel.

The payload format changes slightly, and that’s the first gotcha.

Find every webhook you depend on

Before migrating, inventory what’s posting. Search your infra for the old domain:

grep -rEl 'webhook\.office\.com|outlook\.office\.com/webhook' \
  ./ci ./terraform ./scripts ./alertmanager

Check the usual suspects: Alertmanager receivers, GitHub Actions secrets, Azure DevOps service hooks, cron scripts, and Grafana contact points. Make a list with the destination channel for each — you’ll recreate one Workflow per channel.

Create the replacement Workflow

In the target channel, use the ”…” menu → Workflows → “Post to a channel when a webhook request is received.” Power Automate generates a flow with three things you care about:

  1. A trigger that produces a new POST URL — this replaces your old webhook URL.
  2. A “Post card in a chat or channel” action that renders what you send.
  3. A JSON schema for the inbound request.

Copy the new URL. You’ll swap it in for the old one everywhere on your inventory list.

Gotcha #1: the payload wrapper changed

The old connector accepted a bare adaptive card or a MessageCard. The Workflow trigger expects the adaptive card wrapped in an attachments envelope:

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "type": "AdaptiveCard",
        "version": "1.5",
        "body": [
          { "type": "TextBlock", "text": "Deploy succeeded", "weight": "Bolder" }
        ]
      }
    }
  ]
}

If you were sending the old MessageCard format (“@type”: “MessageCard”), convert those to adaptive cards now — MessageCard support is going away with the connectors. This conversion is the bulk of the migration work, and it’s the perfect place to improve the cards rather than port them verbatim.

Gotcha #2: no Authorization header, different errors

The new URL doesn’t use a bearer token, but it does validate the request shape. A malformed payload fails silently or returns a 4xx that doesn’t always make it obvious what’s wrong. Test each new URL with curl before flipping production:

curl -X POST "$NEW_WORKFLOW_URL" \
  -H "Content-Type: application/json" \
  -d @test-card.json

A successful post returns 202 Accepted. If you get a 200 with HTML, you’ve pasted the wrong URL.

Let AI convert MessageCards to adaptive cards

I had a backlog of old MessageCard JSON across scripts. Rather than hand-convert each, I fed them to a model: “Convert this Office 365 MessageCard JSON to an equivalent Adaptive Card 1.5 wrapped in the Teams Workflow attachments envelope.” It handled the structural mapping — sections to containers, facts to FactSets, potentialAction to actions — and I reviewed the output. For a batch of 30 cards that turned a tedious afternoon into 20 minutes. The Microsoft Teams prompts collection has a conversion prompt for this.

Roll out without an outage window

Don’t big-bang it. The safe sequence:

  • Run both in parallel where you can — keep the old webhook live while you point a non-critical sender at the new URL and confirm cards render.
  • Migrate low-stakes channels first (build notifications) before incident channels.
  • Update secrets, not code, where possible — if your webhook URL lives in a CI secret or Alertmanager config, swapping the value is a one-line change.
  • Watch for the cutover date. Microsoft has published retirement milestones; treat them as hard deadlines, not suggestions.

After the migration

Once you’re on Workflows, you get a bonus: the flow is a full Power Automate flow. You can add steps — log to a list, branch on severity, fan out to multiple channels — without touching the sender. The webhook was a dead end; the Workflow is a starting point.

Inventory first, convert MessageCards to adaptive cards, test each URL with curl, and migrate least-critical channels first. Do it before the deprecation date, not during the incident where your alerts silently stopped arriving.

Verify retirement dates against Microsoft’s current documentation. Card formats and Workflow behavior can change between Teams client versions.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.