Learn how to detect throttling events before they impact production by querying Power Platform Admin APIs from a scheduled cloud flow. This lesson covers quota measurement, alert logic with configurable thresholds, and automated remediation patterns that pause non-critical flows when capacity is near exhaustion.

Picture this: It's 9:47 AM on a Tuesday. Your company's order fulfillment workflow has been running flawlessly for months. Then, without warning, hundreds of orders stop processing. Your support queue fills up. Someone on the operations team pings you: "Is the automation down?" You check Power Automate and find a wall of throttled runs. The platform hit its API request quota hours ago, and nobody knew until customers started complaining.
This is exactly the kind of incident that quota monitoring is designed to prevent. Power Platform enforces hard limits on API requests — limits that scale with your licensing tier and can be consumed surprisingly fast by high-frequency flows, especially if you have multiple environments, multiple flows, and a growing user base. The good news is that Microsoft exposes telemetry and quota data through the Power Platform Admin APIs, which means you can build a monitoring layer that watches your consumption in real time, alerts before you hit the ceiling, and even triggers automated remediation to buy you time before human intervention.
By the end of this lesson, you will have a working mental model and practical implementation plan for a quota monitoring and auto-remediation system built entirely inside Power Platform — using scheduled cloud flows, the Admin API, and adaptive alerting logic.
What you'll learn:
You should be comfortable building basic cloud flows in Power Automate and understand the concept of HTTP actions. If you haven't worked with HTTP requests in flows before, review the lesson on Advanced Power Automate: Custom Connectors and HTTP Actions for Production Integration first. You'll also benefit from understanding how environments are structured — the lesson on The Power Platform Admin Center for Flow Owners: Environments, Capacity, and Tenant Settings gives you that foundation.
You'll need:
Before you can monitor quotas, you need to understand exactly what you're measuring. Power Platform API requests are not the same thing as flow runs. An API request is any call that a flow makes to a Microsoft service — reading a SharePoint list item, updating a Dataverse record, sending a Teams message, retrieving a Blob from Azure Storage. Every action in every flow that touches a connector counts.
Microsoft allocates API requests per user per day based on license type:
These quotas are pooled across your tenant and replenished every 24 hours at midnight UTC. When your tenant collectively exhausts the quota, flows don't fail immediately — Power Platform throttles them, which means it queues requests and processes them slower. For near-real-time processes like order fulfillment or incident response, "slower" is effectively "broken."
Key insight
Throttling is a gradual event, not a cliff. Flows degrade progressively as the quota is consumed. A flow that normally runs in 30 seconds might take 10 minutes during heavy throttling, and eventually return HTTP 429 errors that cause action failures. You want to detect the leading edge of this degradation, not the crash.
The detailed breakdown of entitlements and how they stack is covered in Capacity, API Request Limits, and Entitlements in Power Platform: A Complete Guide for Enterprise Architects. For this lesson, we'll focus on the monitoring and response mechanics.
The Power Platform Admin APIs use OAuth 2.0. You cannot call them with a user's delegated credentials inside a flow — you need a service principal, which is an Azure AD application registration that acts on behalf of your organization without a human signing in.
Here's how to configure it:
Step 1: Register an app in Azure AD
Open the Azure portal, navigate to Azure Active Directory, then select App registrations and click New registration. Give it a name like PowerPlatformMonitor. Leave the redirect URI blank for now and click Register.
Once created, note the Application (client) ID and the Directory (tenant) ID — you'll need both.
Step 2: Add API permissions
In your new app registration, navigate to API permissions → Add a permission → APIs my organization uses. Search for "Power Platform API" (it may also appear as https://service.powerapps.com/). Add the Flow.Read.All and Flow.Manage.All delegated/application permissions. Then also add the Microsoft Graph permission Directory.Read.All for tenant context lookups.
Click Grant admin consent to activate these permissions.
Step 3: Create a client secret
Navigate to Certificates & secrets → New client secret. Set an expiration and save the secret value immediately — you won't see it again. Store this in Azure Key Vault rather than hardcoding it in your flows. The lesson on Integrating Power Automate with Azure Key Vault and Managed Identities walks you through the exact pattern for retrieving secrets securely at runtime.
Warning
Never store client secrets in flow environment variables in plain text. If your solution is exported and shared, those values travel with it. Key Vault references or Managed Identity are the right patterns for production.
The Power Platform Admin API endpoint for capacity consumption is:
GET https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/{environmentId}/flowQuotas?api-version=2016-11-01
And for tenant-level request telemetry:
GET https://api.powerplatform.com/appmanagement/environments/{environmentId}/flows?api-version=2022-03-01-preview
Let's build the monitoring flow step by step.
Getting an Access Token
First, your flow needs to authenticate as the service principal. Add an HTTP action with the following configuration:
Method: POST
URI: https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token
Headers:
Content-Type: application/x-www-form-urlencoded
Body:
grant_type=client_credentials
&client_id={your-app-client-id}
&client_secret={your-secret-from-keyvault}
&scope=https://service.powerapps.com/.default
Parse the response using the Parse JSON action. The token is in the access_token field. Store it in a string variable called bearerToken.
Querying Flow Run Statistics
Now use a second HTTP action to retrieve flow run data:
Method: GET
URI: https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/@{variables('environmentId')}/flows?api-version=2016-11-01&$top=100
Headers:
Authorization: Bearer @{variables('bearerToken')}
Content-Type: application/json
The response returns a collection of flow objects. Each flow has properties including its status, last modified date, and — critically — trigger information. But run-level telemetry requires a second call per flow:
Method: GET
URI: https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/@{variables('environmentId')}/flows/@{items('Apply_to_each_flow')?['name']}/runs?api-version=2016-11-01&$filter=startTime ge @{variables('windowStart')}
Headers:
Authorization: Bearer @{variables('bearerToken')}
Tip
Set windowStart to the current time minus one hour using the Power Automate expression addHours(utcNow(), -1). This gives you a rolling hourly view of run activity without pulling the full history on every poll cycle.
Wrap this second call in an Apply to Each loop that iterates over your critical flows (not every flow in the environment — that's expensive and noisy). Maintain a separate array variable called criticalFlowIds populated from an environment variable so you can update the list without touching the flow logic.
Throttling shows up in two places: flow run history and action-level telemetry. Within a flow run, a throttled action returns HTTP status 429 with a Retry-After header. In run history, throttled runs appear with a status of Throttled rather than Succeeded or Failed.
When you parse the run results from the Admin API, filter for throttled status:
{
"filter": "@{equals(items('Process_runs')?['properties']?['status'], 'Throttled')}"
}
Implement a counter variable called throttledRunCount. Inside the Apply to Each that processes runs, add a Condition action:
items('Process_runs')?['properties']?['status'] is equal to ThrottledthrottledRunCount by 1After the loop, calculate a throttle rate:
throttleRate = divide(variables('throttledRunCount'), variables('totalRunCount'))
A throttle rate above 5% in a one-hour window is your first alert threshold. Above 25% means you have an active production problem.
Note
The Admin APIs have their own rate limits (roughly 60 requests per minute per client). Your monitoring flow itself can get throttled. Design it to run every 15 minutes rather than continuously, and use exponential backoff on the token request if you get a 429 from the auth endpoint.
You can also detect throttling at the tenant level by querying the capacity summary endpoint:
GET https://api.powerplatform.com/analytics/environments/{environmentId}/flows/apiusage?startTime={iso-start}&endTime={iso-end}&api-version=2022-03-01-preview
This returns a requestsConsumed and requestsAllowed value you can use to compute a utilization percentage:
utilizationPct = divide(body('Parse_Capacity')?['requestsConsumed'], body('Parse_Capacity')?['requestsAllowed'])
Now that you can measure throttle rate and utilization percentage, you need a conditional alert tree. Think of it as three tiers:
| Threshold | Condition | Action |
|---|---|---|
| Info | utilizationPct ≥ 0.60 | Log to Application Insights |
| Warning | utilizationPct ≥ 0.80 OR throttleRate ≥ 0.05 | Send Teams alert to ops channel |
| Critical | utilizationPct ≥ 0.95 OR throttleRate ≥ 0.25 | Send Teams alert + trigger remediation child flow |
Implement this as nested Condition actions in your monitoring flow. For the Teams alerts, use the Post message in a chat or channel action. Include the following in the message body:
⚠️ Power Automate Quota Alert — @{utcNow()}
Environment: @{variables('environmentName')}
Utilization: @{mul(variables('utilizationPct'), 100)}%
Throttled runs (last 1hr): @{variables('throttledRunCount')} of @{variables('totalRunCount')}
Throttle rate: @{mul(variables('throttleRate'), 100)}%
Action required: Review flow run history in PPAC and consider pausing non-critical scheduled flows.
For logging to Application Insights at the Info tier, use the HTTP action to POST to the Track Event endpoint with your instrumentation key. This creates a searchable, queryable audit trail over time — essential when you want to identify trending patterns rather than just point-in-time spikes. The broader monitoring strategy for this is covered in Building a Power Automate Monitoring and Alerting System.
Key insight
Logging every monitoring cycle to Application Insights — not just when thresholds are breached — lets you build trend dashboards in Azure Monitor. You'll start to see patterns: quota consumption spikes every Monday morning when batch processes kick off, or a specific flow that consumes 40% of daily requests. That visibility is how you get ahead of incidents.
When the Critical threshold fires, you have minutes before production flows start failing for customers. Automated remediation buys time for your team to respond. Here are two practical patterns.
Pattern 1: Pause Non-Critical Scheduled Flows
Maintain an environment variable (type: JSON) called nonCriticalFlowIds — a list of flow IDs for scheduled, non-time-sensitive processes like weekly reports, data archiving jobs, or analytics aggregations. When the critical alert fires, a child flow loops through this list and calls the Admin API to disable each one:
Method: POST
URI: https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/@{variables('environmentId')}/flows/@{items('Flow_to_pause')?['id']}/stop?api-version=2016-11-01
Headers:
Authorization: Bearer @{variables('bearerToken')}
Log each disabled flow ID to a SharePoint list with the timestamp and the monitoring run ID that triggered the action. This creates an audit trail and provides the data your recovery flow needs to re-enable everything once utilization drops back below 70%.
Warning
Be very deliberate about which flows go on the non-critical list. Disabling the wrong flow in a crisis compounds the incident. Review this list with your business stakeholders at least quarterly, and store it in a governed location — not in someone's personal OneDrive.
Pattern 2: Throttle-Aware Retry with Exponential Backoff
For flows that you can't pause, build throttle-awareness into the flow itself. When an action returns a 429 status, read the Retry-After header from the action's response headers and use it to set a dynamic delay before retrying. This pattern is fully explored in Handling Pagination and Throttling When Querying Large Datasets in Power Automate, but here's the core expression:
int(outputs('HTTP_Action')?['headers']?['Retry-After'])
Feed that integer into a Delay action (set to seconds) before your retry attempt. This prevents your flow from hammering an already-throttled platform and worsening the congestion.
For high-volume processing workloads, consider offloading to Azure Service Bus queues so that flow runs are decoupled from request volume spikes. The event-driven automation with Azure Service Bus pattern is specifically designed for this scenario.
Build a working quota monitor for your own environment using these steps:
Step 1: Create the app registration in Azure AD as described above. Store the client ID, tenant ID, and client secret in Azure Key Vault.
Step 2: Create a scheduled cloud flow that runs every 15 minutes. Name it Quota Monitor - [Environment Name].
Step 3: Add the token acquisition HTTP action. Parse the response and store access_token in a variable.
Step 4: Call the flow list endpoint for your target environment. In a separate Compose action, hardcode an array of 3-5 flow names you want to monitor closely (pick real flows from your environment).
Step 5: For each monitored flow, call the runs endpoint filtered to the last hour. Count total runs and runs with status Throttled.
Step 6: Compute throttleRate using the divide expression. Add a Condition: if throttleRate is greater than 0.05, send yourself a Teams message with the flow name and rate.
Step 7: Run the flow manually and verify the Teams message arrives. Check that the token acquisition succeeded and the run list is populated.
Step 8: Enable the 15-minute schedule and let it run for a day. Review what you see. If you have any flows running frequently, you'll likely see non-zero run counts within the first polling cycle.
As a stretch goal, add a SharePoint list to log every monitoring result (not just alerts) with columns: Timestamp, EnvironmentId, FlowId, TotalRuns, ThrottledRuns, ThrottleRate. This gives you a historical dataset you can analyze later.
Mistake 1: Using delegated permissions instead of application permissions
The Admin API calls must use application permissions (client credentials flow), not delegated permissions. If you authenticate as a user, you'll get 403 errors on tenant-wide endpoints even if that user is an admin. Double-check your app registration permissions and ensure you selected "Application" not "Delegated" when adding them.
Mistake 2: Monitoring too many flows in a single polling cycle
If you loop over every flow in an environment (potentially hundreds) and make a runs API call for each one, your monitoring flow will itself consume enormous API quota and potentially get throttled. Limit monitoring to your critical production flows and use a separate, lower-frequency flow for comprehensive environment scanning.
Mistake 3: Treating throttle rate as binary
A throttle rate of 1% doesn't mean everything is fine. If that 1% is concentrated on your most critical flow — the one that processes payments — it's a serious signal. Break your monitoring down by flow priority, not just aggregate rates.
Mistake 4: Not handling API version mismatches
The Power Platform Admin API is versioned and evolves. If you get a BadRequest or UnsupportedApiVersion error, check the api-version parameter in your URI. The 2016-11-01 version covers most flow management endpoints, but newer analytics endpoints use 2022-03-01-preview or later. Always test your API calls in a REST client like Bruno or Postman before embedding them in a flow.
Mistake 5: Forgetting to re-enable paused flows
If your critical alert fires and the remediation flow disables non-critical flows, you need an equally automated recovery process. Build a separate scheduled flow (runs every 30 minutes) that checks current utilization and re-enables paused flows once the environment drops below your warning threshold. Without this, you'll come back the next morning to find scheduled reports haven't run in 18 hours.
Tip
When re-enabling flows from a SharePoint audit list, add a check that the flow was disabled by your monitoring system (not by an administrator manually). You don't want automated recovery accidentally re-enabling a flow that was deliberately paused by your team for unrelated reasons. Add a DisabledBy column to your audit list and only re-enable rows where DisabledBy equals QuotaMonitor.
You now have a complete mental model and implementation blueprint for quota monitoring in Power Automate. The core pattern is: authenticate with a service principal, poll the Admin APIs on a 15-minute schedule, calculate throttle rate and utilization percentage, alert at configurable thresholds, and trigger automated remediation when the situation is critical.
The most important thing to take away is that quota exhaustion is preventable. The data is available through the Admin APIs. The alerting logic is buildable in a standard cloud flow. The remediation patterns — pausing non-critical flows, implementing retry-after logic, decoupling with queues — are all standard enterprise patterns. What prevents teams from doing this is usually not technical complexity but the assumption that "we'll deal with it when it happens." This lesson gives you the tools to not wait.
Where to go next: