---
title: "Automate Expense Report Approvals with Power Automate"
description: "Build a Power Automate approval flow on a SharePoint list that routes expense reports, closes the self-trigger loop, and exports approved spend for finance."
canonical: "https://adamtheautomator.com/power-automate-expense-approval-flow/"
---

# Automate Expense Report Approvals with Power Automate

> Build a Power Automate approval flow on a SharePoint list that routes expense reports, closes the self-trigger loop, and exports approved spend for finance.

Source: https://adamtheautomator.com/power-automate-expense-approval-flow/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Automate Expense Report Approvals with Power Automate](https://adamtheautomator.com/wp-content/uploads/publisher/3ec5d9c85b2b81b19274c73baf4c55f3/98f4af306255355a84e7293721f7eba0ae787ac2055f021d4fddbae4f4385bee.webp)

# Automate Expense Report Approvals with Power Automate

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)9 October 202610 min. read

Categories: [Business Process Automation](/category/business-process-automation/)

Tags:[Power Automate](/tag/power-automate/)[SharePoint](/tag/sharepoint/)[Microsoft 365](/tag/microsoft-365/)[Automation](/tag/automation/)

Table of Contents

*   [Why Manual Expense Reports Drain Your Finance Team](#why-manual-expense-reports-drain-your-finance-team)
*   [Prerequisites for Building the Flow](#prerequisites-for-building-the-flow)
*   [Build the SharePoint List That Holds the Data](#build-the-sharepoint-list-that-holds-the-data)
*   [Choice Columns Beat Free Text](#choice-columns-beat-free-text)
*   [Wire the Approval Action into the Flow](#wire-the-approval-action-into-the-flow)
*   [Branch on the Outcome Field](#branch-on-the-outcome-field)
*   [Handle Rejection and Resubmission Without a Trigger Loop](#handle-rejection-and-resubmission-without-a-trigger-loop)
*   [Rework Without a New Record](#rework-without-a-new-record)
*   [Route High-Value Reports to a Second Approver](#route-high-value-reports-to-a-second-approver)
*   [Export Approved Expenses for Finance](#export-approved-expenses-for-finance)
*   [Flatten the Rows Before You Build the File](#flatten-the-rows-before-you-build-the-file)
*   [Where Expense Approval Flows Break](#where-expense-approval-flows-break)
*   [Approval Timeouts Have a Ceiling](#approval-timeouts-have-a-ceiling)
*   [Response Strings Are Case-Sensitive](#response-strings-are-case-sensitive)
*   [Pagination Hides Missing Rows](#pagination-hides-missing-rows)
*   [Frequently Asked Questions](#frequently-asked-questions)
*   [Can I Automate Expense Report Approvals Without a Premium License?](#can-i-automate-expense-report-approvals-without-a-premium-license)
*   [How Do I Keep the Approval Flow from Triggering Itself?](#how-do-i-keep-the-approval-flow-from-triggering-itself)
*   [How Do Approvers Get Notified Before an Approval Expires?](#how-do-approvers-get-notified-before-an-approval-expires)
*   [Can I Schedule the CSV Export Instead of Running It by Hand?](#can-i-schedule-the-csv-export-instead-of-running-it-by-hand)
*   [Key Takeaways and Where to Go Next](#key-takeaways-and-where-to-go-next)

You are the approval bottleneck. Every expense report your team files lands in your inbox, and each one sits there until you read it, judge it, and reply, because nothing gets reimbursed without your decision.

This tutorial replaces that inbox with a [Power Automate](https://learn.microsoft.com/en-us/power-automate/) approval flow for expense report automation that reads from a [SharePoint](https://learn.microsoft.com/en-us/sharepoint/) list and keeps every decision in one place. You will build the list schema, wire the approval action to a real approver, and handle the reject-and-resubmit cycle so a rejected report comes back for edits instead of spawning a duplicate record. Then you will schedule a CSV export finance can reconcile at month end. Along the way you will meet the two failures that sink real expense flows: an approval that outlives the flow run-duration limit, and a trigger loop that re-fires the flow every time it updates its own item.

## Why Manual Expense Reports Drain Your Finance Team

A manual expense report costs you the labor around the receipt, not the receipt itself. The Global Business Travel Association (GBTA) [estimates the average cost to process one expense report](https://gbta.org/how-much-do-expense-reports-really-cost-a-company/) at roughly $58, built from about 20 minutes of finance labor per report. An [Aberdeen Group analysis of small and midsize businesses](https://www.paywithextend.com/resource/how-much-is-manual-expense-management-really-costing-you) put the same figure at $35.02. Two different numbers, same conclusion: you are paying a skilled person to shuffle paper.

Errors inflate that number fast. The same GBTA research found that about 19% of expense reports arrive with errors or missing information, and correcting a single bad report costs an additional $52 and about 18 minutes. At high volume, that correction work becomes a second job for whoever owns the queue.

Here is the same pipeline after automation. The figures below are cited third-party estimates from those studies, and the ranges are illustrative.

| Measure | Manual process | Automated flow |
| --- | --- | --- |
| Cost per report | $35.02 to $58.00 | about $6.85 |
| Routing time | about 20 minutes of labor | automatic |
| Error rate | about 19% | near zero with choice columns |

_Table 1: Cited cost estimates for manual versus automated expense processing._

The gap between those columns comes from the data structure underneath the flow, and that structure is the first thing you build.

## Prerequisites for Building the Flow

If you want to follow along hands-on, you will need:

*   A Microsoft 365 plan or Power Automate license that includes flow creation. Approval flows built from Standard connectors (Approvals, SharePoint, Teams) run under these licenses without a Premium per-flow plan, per the [Power Automate licensing FAQ](https://learn.microsoft.com/en-us/power-platform/admin/power-automate-licensing/faqs).
    
*   A SharePoint site where you can create a list, because the flow reads its trigger and writes each status change from that list.
    
*   Permission to create a flow in your default environment, since the Approvals connector stores approval records in Dataverse, and [Power Automate provisions that database](https://learn.microsoft.com/en-us/power-automate/get-started-approvals) the first time an approval flow runs.
    

If you are only reading to plan the build, you can skip the tenant access, but the trigger and the column names below are what you will configure.

## Build the SharePoint List That Holds the Data

The flow is only as good as the columns it reads. A [SharePoint list](https://adamtheautomator.com/power-automate-document-intake-pipeline/) gives employees, approvers, and finance one table to work from, and its version history records every status change an audit trail depends on ([SharePoint list versioning](https://support.microsoft.com/en-us/sharepoint/lists/documents-and-library/enable-and-configure-versioning-for-a-list-or-library)).

Create a list named **Expense Reports** and add these columns:

| Column | Type | Why it matters |
| --- | --- | --- |
| Title | Single line of text | Unique expense ID the flow references in every notification |
| Employee | Person or Group | Resolves the submitter and the notify target |
| Amount | Currency | Drives threshold routing to a second approver |
| Category | Choice | Restricts values so spend reporting rolls up cleanly |
| Receipt | Attachments | Proof of purchase; required before save |
| ApprovalStatus | Choice | Tracks New, Under Review, Approved, Rejected, Resubmitted |

_Table 2: Column schema for the Expense Reports list._

### Choice Columns Beat Free Text

A free-text category field gives you two spellings of “lunch” and a spend report that splits the same expense in half. A Choice column forces a value from a fixed list, so your monthly export and any Power BI view over it both group correctly. Configure the list to require at least one attachment before an item saves, and the missing-receipt rejection leaves your queue before it arrives.

* * *

_**Pro Tip: Turn on list versioning before you collect a single row. Version history is the audit trail you point finance at when someone questions a status change, and you cannot backfill it after the fact.**_

* * *

With the columns defined, the list can accept a submission. The next piece decides what happens the moment one lands.

## Wire the Approval Action into the Flow

In the Power Automate maker, start an automated cloud flow and choose the SharePoint trigger **When an item is created or modified**, which fires whenever an employee submits a row or edits an existing one ([SharePoint connector triggers](https://learn.microsoft.com/en-us/sharepoint/dev/business-apps/power-automate/sharepoint-connector-actions-triggers)). Then add the Approvals action **Start and wait for an approval** and set **Approval type** to **Custom Responses - Wait for one response**, which gives your approver three buttons instead of two: Accept, Reject, and Need more info ([approval flows with custom responses](https://learn.microsoft.com/en-us/power-automate/create-approval-response-options)). The expressions in this tutorial match the current Workflow Definition Language in the Power Automate cloud service, tested on the Standard Approvals connector in a Microsoft 365 E3 tenant.

### Branch on the Outcome Field

After the approval action, add a **Switch** action and select the approval’s **Outcome** field. Map Accept to a status update of Approved, Reject to Rejected with the approver’s comment captured, and Need more info to a notification that asks the employee for the missing detail. The canvas below shows that finished shape, from the SharePoint trigger through the switch that fans each outcome into its own path.

![Expense approval flow](https://adamtheautomator.com/wp-content/uploads/publisher/e92abb6b782994f0fce805a1ad6faf91fc9dbf4ddb28b6ce3596ec77396a2e7a.jpg)

* * *

_**Key Insight: Pull the approver’s email from the list item or a manager lookup instead of typing it into the action. A staffing change then routes the next report to the new manager on its own.**_

* * *

## Handle Rejection and Resubmission Without a Trigger Loop

A created-or-modified trigger is where many expense flows break. Your trigger fires on **created or modified**, and your flow finishes by updating the same item’s ApprovalStatus. SharePoint records that update as a modification, so the flow triggers itself, writes again, and loops until Microsoft throttles it and turns the flow off.

The fix is a trigger condition ([customize your triggers with conditions](https://learn.microsoft.com/en-us/power-automate/customize-triggers)), a boolean expression the platform evaluates before the run starts. When the condition is false, the run never begins and consumes no actions. Filter on status so the flow wakes only for items that still need a decision:

```text
@not(or(equals(triggerOutputs()?['body/ApprovalStatus/Value'], 'Approved'), equals(triggerOutputs()?['body/ApprovalStatus/Value'], 'Rejected')))
```

An item already marked Approved or Rejected makes the condition false, so the flow stays asleep. When an employee edits a rejected report and sets the status back to Resubmitted, the condition returns true and a fresh approval goes out.

### Rework Without a New Record

On a Reject outcome, update ApprovalStatus to Rejected, write the approver’s comment into a Comments column, and notify the employee. The employee edits that same item, changes the status to Resubmitted, and the trigger condition lets the flow fire again. One record carries as many review cycles as the report needs, which keeps the full history in a single row for finance.

The trigger condition settings below are where that loop gets closed.

![Trigger conditions panel](https://adamtheautomator.com/wp-content/uploads/publisher/d3fac70adeb42bac0b20c21959a42451e493bab5a76b69a10b1f66b19f6e0b6a.jpg)

* * *

_**Warning: Test the condition against both states before you trust it. A single wrong status value (‘Resubmitted’ versus ‘Resubmit’) leaves the flow asleep when it should run or looping when it should stop, and Flow Checker will not catch the mismatch.**_

* * *

## Route High-Value Reports to a Second Approver

A $30 lunch and a $4,000 conference trip should not take the same path. Power Automate ships four approval types, and the right one depends on who has to agree.

| Approval type | Behavior | Use it when |
| --- | --- | --- |
| Approve/Reject - First to respond | Any one approver can decide | A single manager signs off |
| Approve/Reject - Everyone must approve | Every approver must respond | A committee owns the budget |
| Custom Responses | You define the buttons | You need Accept, Reject, and Need more info |
| Sequential approval | Approvals run in order | Finance signs off only above a threshold |

_Table 3: Approval types and when each one fits an expense flow._

For a two-tier expense flow, add a **Condition** on the Amount column. Below your threshold, send the report to the employee’s manager. At or above it, run the approvals in sequence so finance signs off only after the manager, which stops a large claim from clearing on one signature ([sequential approvals](https://learn.microsoft.com/en-us/power-automate/set-up-sequential-approvals)). Pick the threshold from your own spending data; a common starting point is the highest amount a manager can approve without a second signature.

## Export Approved Expenses for Finance

Reconciliation should run on a schedule so nobody has to remember to export. Create a second flow with a **Recurrence** trigger and point a **Get items** action at the Expense Reports list, filtered server-side so SharePoint returns only the rows finance cares about:

```text
ApprovalStatus eq 'Approved'
```

Get items returns 100 items by default and pages automatically; once a list grows past 5,000 rows, turn on **Pagination** in the action settings so the flow walks the full set instead of stopping at the list view threshold ([Get items and pagination guidance](https://learn.microsoft.com/en-us/sharepoint/dev/business-apps/power-automate/guidance/working-with-get-items-and-get-files)).

### Flatten the Rows Before You Build the File

Raw SharePoint output is nested JSON carrying metadata finance does not want, and feeding it straight into a table action fails with a “value must be of type Array” error. Flatten it with a **Select** action that maps only the business columns:

```text
Expense ID : @item()?['Title']
Employee   : @item()?['Employee']?['DisplayName']
Date       : @item()?['ExpenseDate']
Amount     : @item()?['Amount']
Category   : @item()?['Category']?['Value']
```

Feed that array into **Create CSV table**, then write the result with a **Create file** action using a timestamped name so each month lands as its own artifact:

```text
ExpenseExport_@{formatDateTime(utcNow(), 'yyyyMMdd')}.csv
```

Point the file at a finance archive library and the audit trail writes itself on schedule ([Data operations actions](https://learn.microsoft.com/en-us/power-automate/data-operations)).

## Where Expense Approval Flows Break

Three failure modes account for most stalled expense flows, and each one comes from a limit you can design around.

### Approval Timeouts Have a Ceiling

Microsoft Learn’s [Limits of automated, scheduled, and instant flows](https://learn.microsoft.com/en-us/power-automate/limits-and-config) states: “Run duration is calculated using a run’s start time and includes flows with pending steps like approvals. After 30 days, any pending steps time out.” A report an approver ignores for a month kills the run, and the abandoned approval request sits in the approver’s action center until an administrator clears it ([known issues with approvals](https://learn.microsoft.com/en-us/power-automate/approvals-known-issues)).

Design for the timeout instead of discovering it. Send the approver a follow-up notification before the ceiling so the request does not sit untouched for weeks, set an **Action timeout** below 30 days, then configure a catch path that runs after the approval action times out. That path can mark the item Escalated and notify a backup approver, so the report keeps moving. When the bottleneck is a person who never responds rather than a status that never changes, [the human-in-the-loop approval pattern for Copilot flows](https://adamtheautomator.com/stop-copilot-auto-approvals-human-loop/) owns the same timeout break from the other direction.

### Response Strings Are Case-Sensitive

A **Condition** that compares the outcome against lowercase “approve” sends every approval down the No branch, and Flow Checker stays quiet about it. Compare against exactly “Approve” and “Reject”.

If you add custom responses, respect the delivery limit: Outlook and Outlook Web Access actionable messages show a maximum of five custom responses per the [documented approvals limits](https://learn.microsoft.com/en-us/power-automate/approvals-known-issues), and they also fail under the “Everyone must approve” type because of the data-size limit on the results field. Keep custom responses to single-approver flows.

### Pagination Hides Missing Rows

A filtered **Get items** that matches nothing in the first 5,000 rows returns empty even when approved expenses exist deeper in the list. Turn on Pagination and index the columns in your filter query to stay under the list view threshold, then re-run the flow and confirm it reaches the older records.

## Frequently Asked Questions

The build above answers the how. These answers cover what readers ask once a Power Automate approval flow goes live, and each one ties back to a decision higher on the page.

### Can I Automate Expense Report Approvals Without a Premium License?

Yes, as long as the flow stays on Standard connectors. The Approvals and SharePoint connectors are Standard, and Teams is included on the same plan, so a Microsoft 365 plan that includes Power Automate covers this entire build. You move to a Premium per-flow or per-user plan only when you add a Premium connector: an HTTP action or a premium data source.

### How Do I Keep the Approval Flow from Triggering Itself?

Filter the trigger. The condition in “Handle Rejection and Resubmission Without a Trigger Loop” makes the platform evaluate your expression before the run starts, so a status write from the flow’s own update never starts a second run. Verify the exact status string the condition compares against, because a mismatch leaves the loop open.

### How Do Approvers Get Notified Before an Approval Expires?

The approval action does not send repeat notifications on its own. Pair it with a delay and a Teams or Outlook notification, or set the cadence in the [modern approvals experience](https://learn.microsoft.com/en-us/power-automate/modern-approvals), so an approver hears about a pending request while they can still act on it.

### Can I Schedule the CSV Export Instead of Running It by Hand?

Yes, and you should. The second flow in “Export Approved Expenses for Finance” runs on a Recurrence trigger, so the approved-expense export lands in the finance archive library on its own schedule with nobody left to remember it.

## Key Takeaways and Where to Go Next

The manual chase disappears when four things line up:

*   Define the SharePoint columns before you build the flow
    
*   Close the self-trigger loop with a trigger condition
    
*   Route by amount so finance only sees the reports that need it
    
*   Export on a schedule so reconciliation never depends on someone’s memory
    

Start with the trigger condition, because a flow that loops against its own updates will burn your request limits per the [Power Automate limits and configuration](https://learn.microsoft.com/en-us/power-automate/limits-and-config) whether or not the rest is right. Then add the export, because that is the artifact finance actually measures you on. If you would rather hand the build to someone who automates business processes for a living, [Adam’s finance workflow work](https://adamtheautomator.com/about-adam/) covers exactly this kind of project.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fpower-automate-expense-approval-flow%2F&text=Automate%20Expense%20Report%20Approvals%20with%20Power%20Automate)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fpower-automate-expense-approval-flow%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fpower-automate-expense-approval-flow%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2026/07/featured_image-3.webp)

### [Power Automate: Build a Reliable AI Document Intake Pipeline](/power-automate-document-intake-pipeline/)

Build a Power Automate intake pipeline that deduplicates Outlook attachments, extracts fields with AI Builder, and routes low-confidence results to Teams.

![](https://adamtheautomator.com/wp-content/uploads/publisher/3ec5d9c85b2b81ec815dd67b3720f831/f1259be740bd3b3dc8b6d6dc209ed026d438ad6ea109e47ae76c353b3f50c00c.webp)

### [Copilot Studio Agents: Triage Support Emails Instantly](/copilot-studio-agents-email-triage/)

Build a Copilot Studio agent that triages support email, tags urgency, extracts ticket details, and routes each message to the right owner.

![](https://adamtheautomator.com/wp-content/uploads/2026/07/featured_image-5.webp)

### [Automate Client Onboarding with Zapier AI and Make](/client-onboarding-automation-zapier-make/)

Build a client onboarding automation as a Zapier Zap with an AI step, rebuild it as a Make scenario, then price Zapier tasks against Make credits.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
