In most IT teams, the first sign of a Microsoft 365 problem is a ticket. Someone from finance says SharePoint won't load. Someone from the US office says Teams is frozen. By the time that ticket surfaces in your queue, five more are forming behind it and users are already frustrated. You are debugging from behind.
Microsoft posts service health updates to the Admin Center within roughly 15 minutes of detecting a degradation. The data is accurate, specific to your tenant, and fully available through the Microsoft Graph API. Most IT teams never touch it automatically. They check the Admin Center dashboard by hand, which means they check it after something already feels wrong.
This is the Power Automate flow that closes that gap. It runs on a schedule, reads the service health feed, and posts to your IT Teams channel the moment something new goes wrong, before the tickets start.
What the Microsoft 365 Service Health API Gives You
The Service Health section of the Microsoft 365 Admin Center tracks the status of every Microsoft-managed service in your tenant: Exchange Online, Teams, SharePoint, OneDrive, Entra ID, Intune, and more. Microsoft categorises each event as an Advisory (worth monitoring), a Service Interruption (degraded or unavailable), or a Service Restoration.
All of that is exposed through the Microsoft Graph Service Communications API at the endpoint /admin/serviceAnnouncement/issues. The response includes the affected service name, the current status, a plain-text description of the impact, and the time the issue was first detected.
The flow queries this endpoint every 15 minutes. When it finds something new, it posts to a dedicated Teams channel in a format your team can read and act on in under 30 seconds.
The Flow at a Glance
Step 1: App Registration in Microsoft Entra ID
The Graph Service Health endpoint requires application-level authentication. Before building the flow, create an app registration in the Microsoft Entra admin center.
- Go to App registrations and create a new registration with any name (for example, "M365 Health Monitor").
- Under API Permissions, add the Microsoft Graph application permission
ServiceHealth.Read.All. Grant admin consent. - Under Certificates and secrets, generate a new client secret. Note the expiry date and set a calendar reminder to rotate it before then.
- Copy the Tenant ID, Client ID, and Client Secret. You will need all three in Power Automate.
This takes roughly 10 minutes and only needs to be done once per tenant.
Step 2: Calling the API in Power Automate
Create a new scheduled cloud flow set to run every 15 minutes. Add an HTTP action for the OAuth token request:
- Method: POST
- URI:
https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/token - Body (form-encoded):
grant_type=client_credentials,client_id=[CLIENT_ID],client_secret=[SECRET],scope=https://graph.microsoft.com/.default
Parse the response with a Parse JSON action to extract the access_token. Then add a second HTTP action:
- Method: GET
- URI:
https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/issues?$filter=status ne 'serviceOperational' - Header:
Authorization: Bearer [access_token from previous step]
Parse the JSON response using the value array. Each item contains the incident ID, service display name, status, and a plain-text description. Run a test flow run and paste in the actual response as the sample schema so Power Automate sets up the field references cleanly.
Step 3: State Management
Power Automate flows are stateless between runs. Without somewhere to store context, the flow would fire a Teams alert every 15 minutes for the entire duration of an ongoing outage. That level of noise gets muted fast.
The fix is a SharePoint list with a single item and a single text column called KnownIncidentIDs. The column stores a JSON-serialised array of incident ID strings.
At the start of each flow run, use the SharePoint Get Item action to read the current value. After the API call, use a Filter Array action to find incidents whose IDs are not already in that stored array. Post alerts only for those new items. Then use Update Item to write the full current array back to SharePoint.
The SharePoint reads and writes add roughly two to three seconds to each flow run. On the 15-minute cycle that overhead is invisible. Once an incident clears and its status returns to serviceOperational, you can clean the stored array of resolved IDs on the next run to keep it tidy, though this is optional.
Step 4: Formatting the Teams Alert
The goal of the Teams message is to surface the right information in under 30 seconds so someone on the team can start communicating to affected users. Four fields cover it:
- Service name, for example "Microsoft Teams" or "Exchange Online"
- Status, for example "Service Interruption" or "Investigating"
- Impact summary: the first 200 characters of Microsoft's own description text
- Link to the issue page in Admin Center:
https://admin.microsoft.com/adminportal/home#/servicehealth/:/alerts/[ID]
Keep the message under 200 words. Your team clicks through to Admin Center for the full picture. The alert's job is to land in the channel, name the affected service clearly, and let people act before the tickets start arriving.
I add one more rule for critical services (Exchange, Teams, Entra ID): a second action that sends an email to my personal inbox in addition to the Teams post. Teams notifications get missed. For an Exchange outage, where Teams itself may be unreachable, a separate email channel is worth the extra 30 seconds to configure.
What to Add Once the Base Flow Is Stable
The core flow handles detection and routing. These additions improve it further once the baseline is running cleanly for a week or two:
- Auto-draft a user-facing status message. Add a step that passes the incident details to an AI API call and returns a short, non-technical description suitable for a status page or a support team's hold message. Takes roughly two extra actions in the flow.
- Tag a Zendesk or Help Scout canned response. When an incident involves a widely used service like Outlook or Teams, automatically enable a macro that acknowledges any ticket mentioning that service with a known-issue note. This alone cuts duplicate ticket volume by a meaningful amount during an active outage.
- Log to a SharePoint history list. Each detected incident gets a new row with the service name, status, start time, and a link to Admin Center. Cheap to add, and after a few months you have a clean record to bring to quarterly infrastructure reviews.
The build takes a few hours the first time, mostly on the Entra app registration and the state management wiring. Iterations after that are fast. The monitoring overhead once it runs is close to zero.
Sources
- Microsoft Graph: Service health and communications overview
- Microsoft Graph: List serviceHealthIssues
- Microsoft Power Automate documentation
Building something similar or running into a specific snag with the Entra registration? Drop me a note and I am happy to compare notes on the setup.
Comments