Guide

API change notifications in Slack and Microsoft Teams

Last checked 2026-11-0910 min read

An API change notification is a message to the teams that call an endpoint, sent when that endpoint changes in a way that can break them. A good one fits on a phone screen and answers four questions: what changed, who it concerns, how serious it is, and what to do. Send it to the consuming team’s own Slack or Microsoft Teams channel, one message per change, and update that message instead of posting again. Graphwake sends exactly that message, only to the teams subscribed to the changed endpoint.

ExamplePull request #1284 · orders-api
#team-checkoutGraphwake in Slack

Breaking change in PR #1284

GET /orders/{id} · orders-api

Owned by payments-team

  • total was removed
  • currency is now required

Author: dana-k

orders-api3 breaking changes
  • checkoutSlack #team-checkout
  • mobile-appSlack #mobile-alerts
  • reportingEmail
  • searchquiet, not subscribed
In Graphwake: impact79/100High
A breaking change reaches only the three teams that subscribed to the endpoints it touches. search stays quiet. The impact score is in Graphwake, not in the message.
On this page
  1. The four parts of a good alert
  2. Example: a hand-built alert
  3. Old Teams webhook URLs no longer work
  4. What Graphwake sends
  5. When a webhook script alone is enough
  6. Questions

The four parts of a good alert

PartWhat it saysExample line
WhatThe endpoint, the service, and the change in plain wordsGET /orders/{id} in orders-api: total removed from the 200 response
WhoWho owns the endpoint and who made the change, so the reader knows whom to askOwned by payments-team · PR #1284 by dana-k
SeverityBreaking or not, and whether it is live or still a pull requestBreaking · not merged yet
ActionWhat the reader should do, and where to answerRead amount instead, or reply on the PR before it merges

The order matters. The title is the first thing people see in the channel and in the notification; in Slack the notification shows the message’s text field, so make that the same one-line summary. Put the endpoint and the word “breaking” there, not the service name or a greeting.

Four habits that make alerts ignored

  • A count instead of a change. “3 breaking changes in orders-api” makes every reader open a link to learn whether it is theirs.
  • `@here` or `@channel`. It pings everyone who is online to tell the one team that cares. People mute the channel, and then they miss the next alert too.
  • A wall of diff. Twenty lines of YAML hide the one line that matters. Link to the diff; say the change in a sentence.
  • A new message for every update. A pull request that is pushed five times should not post five alerts. Edit the first message and reply in its thread when something important happens.

Example: a hand-built alert

If you send alerts yourself, from a CI job or a script, this is a shape that holds the four parts. The text sits in the fields each platform uses for notification previews.

Slack: an incoming webhook

  1. Create a Slack app

    At api.slack.com/apps, choose Create New App, pick a name and the workspace.

  2. Turn on incoming webhooks

    Open Incoming Webhooks, switch on Activate Incoming Webhooks, then Add New Webhook to Workspace and pick the consuming team’s channel.

  3. Store the URL as a secret

    The URL contains a secret. Keep it in your CI secret store, never in the repository: Slack looks for leaked webhook URLs and revokes them.

json
{
  "text": "Breaking change: GET /orders/{id} (orders-api)",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Breaking change: `GET /orders/{id}`* in orders-api"
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Removed the required property `total` from the 200 response.\nOwned by payments-team · PR #1284 by dana-k · not merged yet\n*What to do:* read `amount` instead, or reply on the PR before it merges."
      }
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Open pull request"
          },
          "url": "https://github.com/example/orders-api/pull/1284"
        }
      ]
    }
  ]
}
Example payload. Endpoint, team and PR are made up.
bash
curl -X POST -H "Content-Type: application/json" \
  --data @alert.json "$SLACK_WEBHOOK_URL"
  • `text` is not optional. With blocks, Slack uses text as the notification and screen-reader fallback. Make it the one-line summary.
  • One webhook, one channel. An incoming webhook posts to the channel picked when it was created; you cannot override the channel, name or icon. Routing to several teams means one URL per team’s channel.
  • No edits. An incoming webhook cannot delete a message, and returns no message ts to edit it with. To edit one message as the pull request moves on, and reply in its thread, you need a Slack app with a bot token: chat.postMessage, then chat.update with the message’s ts, and thread_ts for replies.
  • Limits. A section’s text is at most 3,000 characters. chat.postMessage allows about one message per second per channel, with short bursts.

Microsoft Teams: a Workflows webhook

Note

Old Teams webhook URLs no longer work

Microsoft retired Office 365 connectors in Teams, including the Incoming Webhook connector, between May 18 and May 22, 2026. A guide that tells you to add the “Incoming Webhook” connector to a channel is out of date. The replacement is a webhook in the Workflows app, built on Power Automate.

  1. Open Workflows on the channel

    In Teams, open More options (…) next to the consuming team’s channel and choose Workflows.

  2. Pick the template

    Choose Send webhook alerts to a channel, confirm the team and channel, and select Save.

  3. Copy the webhook URL

    Copy the link the workflow shows and store it as a secret, like the Slack URL.

  4. Add a co-owner

    A workflow belongs to the person who created it, not to the channel. Add a co-owner so alerts do not stop when that person leaves.

json
{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.4",
        "body": [
          {
            "type": "TextBlock",
            "text": "Breaking change: GET /orders/{id}",
            "weight": "Bolder",
            "size": "Medium",
            "wrap": true
          },
          {
            "type": "TextBlock",
            "text": "Removed the required property total from the 200 response.",
            "wrap": true
          },
          {
            "type": "FactSet",
            "facts": [
              {
                "title": "Service",
                "value": "orders-api"
              },
              {
                "title": "Owner",
                "value": "payments-team"
              },
              {
                "title": "Status",
                "value": "PR #1284, not merged yet"
              },
              {
                "title": "What to do",
                "value": "Read amount instead, or reply on the PR"
              }
            ]
          }
        ],
        "actions": [
          {
            "type": "Action.OpenUrl",
            "title": "View pull request",
            "url": "https://github.com/example/orders-api/pull/1284"
          }
        ]
      }
    }
  ]
}
Example payload. Endpoint, team and PR are made up.
  • Adaptive Cards. Workflows webhooks take Adaptive Card and MessageCard payloads; MessageCard buttons that post back do not work, so use an Adaptive Card. A link button (Action.OpenUrl) is fine.
  • Who posts it. The message shows the Workflows bot, not your name or icon.
  • Limits. A message can be at most 28 KB, and more than four requests a second are throttled. Retry with backoff.
  • Private channels can be picked in the Workflows app since April 2026.

Email: the fallback that always works

Some teams live in email, and chat channels break: a bot is removed, a channel is archived. Put the severity and the endpoint in the subject, because that is all most people read: “[BREAKING] GET /orders/{id} (orders-api)”. Then the same four parts in the body.

See who your next breaking change reaches.Paste a spec URL or add one CI step. 7-day free trial. Cancel before day 7 and you pay nothing.
Start free trial

What Graphwake sends

Graphwake builds these messages for you from your OpenAPI spec and sends each one to the teams subscribed to the endpoint, in the channel each team picked: Slack, Microsoft Teams or email. The one exception, a one-time note to a team Discovery suggests, is below. Every team has at most one chat channel. The examples below follow the message format Graphwake uses; names and links are made up.

text
Breaking change in PR #1284
Service: orders-api
Endpoint: GET /orders/{id}
Owned by payments-team
Change: Removed the required property `total` from the response with the `200` status
Author: dana-k
PR: https://github.com/example/orders-api/pull/1284
[ Open pull request ]
Example: a Slack message to the checkout team while the pull request is open.

In Slack a breaking change gets a siren emoji before the title; in Teams the same lines arrive as an Adaptive Card with a highlighted title and a View pull request button. There is one message per endpoint for each subscribed team, so a team reads only about the endpoints it calls.

text
Subject: [BREAKING] New change notification: GET /orders/{id} (orders-api)

Endpoint: GET /orders/{id}
Service: orders-api
Owned by payments-team
Change: Removed the required property `total` from the response with the `200` status
Breaking: yes, breaking change
Status: new notification
This change is not live yet (open pull request).
Author: dana-k
PR: https://github.com/example/orders-api/pull/1284
Example: the same change by email.

How the message changes as the pull request moves

What happensIn Slack or TeamsBy email
The PR is pushed againThe same message is edited to show the current stateNo new mail
A non-breaking change becomes breaking (teams on “All changes”)Edited, plus a thread reply: “This change is now breaking.”A new mail
The PR mergesTitle becomes “Published: …”, plus a reply: “Published to live.”“Change published” mail
The PR closes without mergingTitle becomes “PR #1284 closed”, plus a reply: “PR closed without merging.”“Change cancelled” mail

A team on the default, breaking changes only, never saw the non-breaking version, so its first message arrives when the change turns breaking. If someone deletes the message, the next update starts a new one. Graphwake never adds @here, @channel or user mentions: text from a spec or a pull request is escaped, so it cannot become a mention or a link.

Discovery can add one more message: a team suggested at 60% or more for the endpoint, but not subscribed, gets a one-time “This may affect you” note when a breaking change goes live. Admins can turn it off.

  • Only subscribed teams

    Each consumer team subscribes to the endpoints it calls. Teams that are neither subscribed nor suggested by Discovery hear nothing.

  • One message per change

    Edited in place as the pull request moves, with a thread reply only when it merges, closes or turns breaking.

  • Email when chat breaks

    If a team’s channel is gone or the bot was removed, that alert goes by email, and admins are told the channel needs fixing.

  • Breaking first

    Teams get breaking changes by default. A team can turn on all changes for itself.

The severity in a Graphwake message is “Breaking change” or “Change”. The impact score of the whole change set, and every team it reaches, are on the change in the dashboard, where each team can mark the change handled.

Set it up

  1. Connect Slack or Microsoft Teams

    An admin connects the Slack workspace, or links the Microsoft tenant and adds the Graphwake app to the teams that should get alerts.

  2. Pick each team’s channel

    On the team’s Notifications tab, pick its channel. A team without a channel gets alerts by email.

  3. Send a test alert

    Send test alert on the same tab sends a test message through the same route a real alert takes.

  4. Subscribe to endpoints

    Each consumer team marks the endpoints it calls. The next breaking change on one of them reaches that team in its own channel.

Good to know

When a webhook script alone is enough

  • One API, a few known consumers. A CI job that posts the alert above to their channels does the job.
  • Every consumer reviews your pull requests. The diff comment there is the alert. See oasdiff in a GitHub Action.
  • Public API consumers. Customers outside your company are not in your Slack; a changelog and an email list reach them.

A script stops scaling when the list of who calls what is the hard part. That list, kept current by the consumer teams, is what routing alerts to the right teams is about, and how to notify consumers of API changes has a notice template for the cases you write by hand.

Questions

Can I still use an Incoming Webhook in Microsoft Teams?

Not the connector. Office 365 connectors in Teams, including Incoming Webhook, were retired in May 2026. Create a webhook with the Workflows app (“Send webhook alerts to a channel”) and send an Adaptive Card to its URL.

Should an API change alert use @here or @channel?

No. Send it to the channel of the team that calls the endpoint instead. A mention pings everyone who is online to reach the few people who care, and channels that ping too often get muted.

Can a Slack incoming webhook edit a message it posted?

No. An incoming webhook cannot delete a message, and returns no message ts to edit it with. To update one message as a pull request changes, use a Slack app with a bot token and chat.update.

Does Graphwake post to a shared announcement channel?

Only if a team picks that channel. Each team chooses one chat channel, and an alert goes only to the teams subscribed to the changed endpoint, plus a one-time note to teams Discovery suggests strongly.

What happens if the Slack or Teams channel is deleted?

Graphwake sends that alert by email instead, to the team’s email channel or its members, and tells the workspace admins that the channel needs fixing.

Pick an endpoint. See who it reaches. 7-day free trial. Cancel before day 7 and you pay nothing.

Start free trial

Sources and last verified

Sources checked on 2026-11-09.