Wicked Smart Data
LearnInsightsAboutContact
Sign InLet's Build
LearnInsightsAboutContact
Sign InLet's Build
Wicked Smart Data

Intelligence, automation, and expert execution — plus an elite library of free knowledge. We turn complexity into competitive advantage.

Start a conversation

Platform

  • Learning Paths
  • Insights
  • RSS Feed

Company

  • About
  • Contact
  • Work With Us

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Wicked Smart Data. All rights reserved.

Intelligence · Automation · Advantage

All Insights
Power Automate

Automating SharePoint-Based Expense Submissions with Power Automate: Capturing Form Data, Routing to a Manager Approver, and Writing Approval Outcomes Back to a List

Build a complete expense approval workflow from scratch: a SharePoint list captures submissions, Power Automate routes them to the right manager, and approval outcomes are written back automatically. By the end, you'll have a fully auditable, hands-off process replacing email chains and manual spreadsheet updates.

⚡ Practitioner19 min readNov 13, 2026Updated Nov 13, 2026
Automating SharePoint-Based Expense Submissions with Power Automate: Capturing Form Data, Routing to a Manager Approver, and Writing Approval Outcomes Back to a List
On this page
  • Introduction
  • Prerequisites
  • Designing the SharePoint List
  • Structuring the Flow: A Bird's-Eye View
  • Building the Trigger and Initial Data Steps
  • Getting the Manager
  • Initialize a Variable for the Manager Email
  • Sending the Approval Request
  • Branching on the Approval Outcome
  • Writing the Outcome Back to SharePoint
  • In the Yes (Approved) Branch
  • In the No (Rejected) Branch
Sending Outcome Notifications to the Submitter
  • Approved notification:
  • Rejected notification:
  • Handling the Finance Team Notification
  • Testing the Flow End to End
  • Hands-On Exercise
  • Common Mistakes & Troubleshooting
  • The approval email shows "[object Object]" for category or status fields
  • The "Get manager" action fails with "Resource not found"
  • The flow trigger fires multiple times for the same item
  • Comments field is null even though the approver left a comment
  • The flow runs but the SharePoint update doesn't reflect the change
  • The approver never receives the email
  • Summary & Next Steps
  • Automating SharePoint-Based Expense Submissions with Power Automate: Capturing Form Data, Routing to a Manager Approver, and Writing Approval Outcomes Back to a List

    Introduction

    Here's a scenario that plays out in organizations every week: an employee fills out an expense report, emails it to their manager, the manager replies with "approved" (or forgets to reply entirely), and then someone in Finance manually updates a spreadsheet with the outcome. When auditors ask about the approval chain for a $3,200 hotel stay from six months ago, the answer is a forwarded email chain buried in someone's inbox. That's not a process — it's a liability.

    Power Automate, working alongside SharePoint and the built-in Approvals connector, gives you the infrastructure to replace that chaos with something auditable, consistent, and largely self-running. By the end of this lesson, you'll have built a complete expense submission workflow: a SharePoint list captures the submission, a flow triggers automatically when a new item is added, an approval request routes to the submitter's manager, and the outcome — approved or rejected, with comments — is written back to that same list item. The entire audit trail lives in SharePoint, queryable and reportable.

    What you'll learn:

    • How to structure a SharePoint list to support an end-to-end approval workflow
    • How to trigger a cloud flow from a SharePoint list item and extract the right data
    • How to use the Approvals connector to send a manager approval request with meaningful context
    • How to branch on the approval outcome using conditions
    • How to write the approval result, comments, and timestamp back to the original SharePoint list item
    • How to send outcome notification emails to the submitter

    Prerequisites

    This lesson assumes you're comfortable with the Power Automate designer interface and have built at least one working flow before. You should understand how triggers work in Power Automate and have a working knowledge of conditions and branching logic. You'll need:

    • A Microsoft 365 account with Power Automate access (Microsoft 365 Business Basic or higher)
    • A SharePoint site where you have at least Site Member access to create lists
    • Permission to create flows in your environment
    • Your organization must have manager relationships populated in Azure Active Directory (so the Office 365 Users connector can resolve a manager from an email address)

    Note

    If your organization's Azure AD manager fields aren't populated, the "Get manager" step will fail silently or throw an error. Check this early by opening the Microsoft 365 People card for a test user and confirming their manager is listed. HR or IT can bulk-populate this if needed.


    Designing the SharePoint List

    Before writing a single flow action, you need a well-designed list. The list schema is the foundation everything else depends on, and fixing it after your flow is in production is painful.

    Create a new SharePoint list called ExpenseSubmissions in your site. Here are the columns you'll need, along with their types and reasoning:

    Column Name Type Notes
    Title Single line of text Use this as the expense description ("Q3 Client Dinner - Chicago")
    SubmitterEmail Single line of text Captures who submitted — don't rely on the Created By field alone
    ExpenseAmount Currency Enables threshold-based routing later
    ExpenseDate Date and Time The date the expense was incurred
    ExpenseCategory Choice Travel, Meals, Software, Equipment, Other
    BusinessJustification Multiple lines of text Required context for the approver
    ReceiptAttached Yes/No Whether a receipt was uploaded
    ApprovalStatus Choice Pending, Approved, Rejected — default to Pending
    ApproverEmail Single line of text Populated by the flow after resolution
    ApprovalComments Multiple lines of text Populated by the flow with the approver's response
    ApprovedDate Date and Time Populated by the flow when a decision is made

    Take a moment to set the default value of ApprovalStatus to Pending in the column settings. This way, any new item is immediately recognizable as awaiting action, and your flow doesn't need to set it.

    Tip

    Add a list view filtered to ApprovalStatus equals Pending and share it with the Finance team. They'll get a live dashboard of everything awaiting approval without touching the flow at all.

    For the ExpenseCategory column, define at least these choices: Travel, Meals & Entertainment, Software & Subscriptions, Office Equipment, Professional Development, Other. These categories will matter if you later extend this flow to route different categories to different approvers or cost centers.

    Once your list is built, test it by manually creating one or two sample items. Make sure the currency field accepts decimal values and that the choice columns display their dropdowns correctly. Catching schema problems before the flow references the columns saves significant debugging time.


    Structuring the Flow: A Bird's-Eye View

    Before opening the designer, map out what this flow needs to do in plain language:

    1. Trigger: A new item is added to the ExpenseSubmissions list
    2. Get submitter's manager: Use the Office 365 Users connector to look up who manages the submitter
    3. Start and wait for an approval: Send a formatted request to the manager, pause until they respond
    4. Branch on the outcome: Did the manager approve or reject?
    5. Update the SharePoint item: Write the decision, comments, timestamp, and approver email back to the list
    6. Notify the submitter: Send an email confirming the outcome

    This is a standard approval workflow pattern, but expense submissions have specific nuances worth getting right: you need to surface the dollar amount prominently, include the business justification, and make it easy for the approver to respond without opening SharePoint.

    Key insight

    The Approvals connector's "Start and wait for an approval" action is synchronous from the flow's perspective — the flow literally pauses at that step until a response arrives. This means your flow run can sit open for hours or days. Power Automate handles this gracefully (flows are durable), but it does mean your run history will show flows in a "Running" state for the duration of the approval window.


    Building the Trigger and Initial Data Steps

    Create a new Automated cloud flow. When asked to choose a trigger, search for SharePoint and select When an item is created. Configure it with:

    • Site Address: Your SharePoint site URL
    • List Name: ExpenseSubmissions

    This trigger fires every time a new list item is created, giving you access to all the column values immediately through dynamic content.

    Getting the Manager

    Add a new action and search for Office 365 Users, then select Get manager (V2). In the User (UPN) field, use the dynamic content SubmitterEmail from the trigger output. This action returns the manager's full profile, including their email address, display name, and job title.

    After this action runs, you'll have access to outputs like:

    • outputs('Get_manager_(V2)')?['body/mail'] — the manager's email address
    • outputs('Get_manager_(V2)')?['body/displayName'] — their display name

    Warning

    Don't use userPrincipalName for sending approval emails — it usually matches the email address, but in some organizations with federated identities, the UPN and mail address differ. Always use mail for the approval recipient.

    Initialize a Variable for the Manager Email

    It's worth storing the manager's email in a variable at this point. Add an Initialize variable action:

    • Name: varManagerEmail
    • Type: String
    • Value: The mail output from the Get manager action

    This lets you reference the manager email in multiple places (the approval action and later in the SharePoint update) without chaining deeply nested expressions everywhere. For more on this pattern, see the guidance on working with conditions, loops, and variables.


    Sending the Approval Request

    Add a new action from the Approvals connector: Start and wait for an approval. This is the action that sends the actual request and pauses the flow.

    Configure it as follows:

    Approval type: Approve/Reject - First to respond

    Title: Use an expression that builds a meaningful subject line:

    Expense Approval Required: @{triggerOutputs()?['body/Title']} — $@{triggerOutputs()?['body/ExpenseAmount']}
    

    This produces something like: Expense Approval Required: Q3 Client Dinner - Chicago — $342.50

    Assigned To: Use your varManagerEmail variable

    Details: This field is your opportunity to give the manager real context. Craft it carefully:

    Expense Submission Details
    --------------------------
    Submitted by: @{triggerOutputs()?['body/SubmitterEmail']}
    Expense Date: @{triggerOutputs()?['body/ExpenseDate']}
    Category: @{triggerOutputs()?['body/ExpenseCategory/Value']}
    Amount: $@{triggerOutputs()?['body/ExpenseAmount']}
    Receipt Attached: @{triggerOutputs()?['body/ReceiptAttached']}
    
    Business Justification:
    @{triggerOutputs()?['body/BusinessJustification']}
    
    Please review and approve or reject below. You may add comments explaining your decision.
    

    Tip

    Notice the ExpenseCategory/Value syntax. Choice columns in SharePoint return an object, not a plain string. If you try to reference ExpenseCategory directly without /Value, you'll get [object Object] in your approval email. This trips up almost everyone the first time.

    Item link: You can optionally add a URL to the SharePoint list item so the approver can open it directly. Build this as:

    @{triggerOutputs()?['body/{Link}']}
    

    Or construct it manually using your site URL and the item ID:

    https://yourcompany.sharepoint.com/sites/Finance/Lists/ExpenseSubmissions/DispForm.aspx?ID=@{triggerOutputs()?['body/ID']}
    

    Requestor: Use the SubmitterEmail dynamic content so the approval system tracks who originally submitted.

    Once configured, the manager receives an email from approvals@microsoft.com containing the details you've written, plus Approve and Reject buttons they can click directly from the email without signing into SharePoint or Power Automate. That frictionless experience is critical for adoption — if approving requires three logins, managers will just ignore the emails.


    Branching on the Approval Outcome

    After the "Start and wait for an approval" action completes (meaning the manager responded), you have access to the approval outcome through dynamic content. The key output is Outcome, which will be either Approve or Reject.

    Add a Condition action. Configure it as:

    • Left value: The Outcome dynamic content from the approval action
    • Operator: is equal to
    • Right value: Approve

    This gives you a Yes branch (approved) and a No branch (rejected). You'll build the SharePoint update and email notification inside each branch.

    Note

    Some flows return Approved with a capital A and trailing 'd' — this varies by connector version. Check the actual run output from a test run before hardcoding the string comparison. You can also use contains(outputs('Start_and_wait_for_an_approval')?['body/outcome'], 'Approve') as your condition expression to match both Approve and Approved.


    Writing the Outcome Back to SharePoint

    Inside both branches of your condition, you'll add a SharePoint: Update item action. This is where the approval result becomes a permanent record.

    In the Yes (Approved) Branch

    Add Update item with:

    • Site Address: Same as your trigger
    • List Name: ExpenseSubmissions
    • Id: The ID dynamic content from the trigger (the item that was created)
    • ApprovalStatus Value: Approved
    • ApproverEmail: varManagerEmail
    • ApprovalComments: The Comments output from the approval action — this is what the manager typed when they responded
    • ApprovedDate: Use utcNow() as an expression

    The Comments field deserves attention. The approval action returns comments as an array (since multiple approvers could each leave comments in parallel flows). For a single-approver flow like this one, use this expression to extract the first comment:

    @{outputs('Start_and_wait_for_an_approval')?['body/responses'][0]['comments']}
    

    If the approver left no comment, this returns an empty string — that's fine. The SharePoint column will just be blank.

    In the No (Rejected) Branch

    The structure is identical, with two differences:

    • ApprovalStatus Value: Rejected
    • The same comment extraction expression applies

    This symmetry is intentional. Whether approved or rejected, you want the same metadata captured: who made the decision, when, and what they said.

    For comprehensive patterns around keeping SharePoint list items updated through their lifecycle, the SharePoint list lifecycle management guide covers archival and business-rule-based updates worth reviewing once you outgrow this basic pattern.


    Sending Outcome Notifications to the Submitter

    Still inside each branch, add a Send an email (V2) action from the Office 365 Outlook connector.

    Approved notification:

    To: SubmitterEmail from the trigger

    Subject:

    ✅ Your Expense Has Been Approved — @{triggerOutputs()?['body/Title']}
    

    Body:

    <p>Hi @{triggerOutputs()?['body/SubmitterEmail']},</p>
    
    <p>Your expense submission has been <strong>approved</strong> by @{outputs('Get_manager_(V2)')?['body/displayName']}.</p>
    
    <p><strong>Expense:</strong> @{triggerOutputs()?['body/Title']}<br>
    <strong>Amount:</strong> $@{triggerOutputs()?['body/ExpenseAmount']}<br>
    <strong>Approved on:</strong> @{utcNow()}</p>
    
    <p><strong>Manager comments:</strong><br>
    @{outputs('Start_and_wait_for_an_approval')?['body/responses'][0]['comments']}</p>
    
    <p>Finance has been notified and your reimbursement will be processed according to the standard schedule.</p>
    

    Rejected notification:

    To: SubmitterEmail from the trigger

    Subject:

    ❌ Expense Submission Requires Revision — @{triggerOutputs()?['body/Title']}
    

    Body:

    <p>Hi @{triggerOutputs()?['body/SubmitterEmail']},</p>
    
    <p>Your expense submission was <strong>not approved</strong> by @{outputs('Get_manager_(V2)')?['body/displayName']}.</p>
    
    <p><strong>Expense:</strong> @{triggerOutputs()?['body/Title']}<br>
    <strong>Amount:</strong> $@{triggerOutputs()?['body/ExpenseAmount']}</p>
    
    <p><strong>Reason given:</strong><br>
    @{outputs('Start_and_wait_for_an_approval')?['body/responses'][0]['comments']}</p>
    
    <p>Please review the feedback above and resubmit with the requested changes, or contact your manager directly if you have questions.</p>
    

    The HTML body formatting is worth the extra keystrokes. Plain text approval notifications get ignored. A clean, structured email with bolded key facts and a clear next step dramatically improves the submitter experience — and reduces the "did my expense get approved?" follow-up messages to Finance.

    For deeper patterns on crafting effective notification emails, the guide on automating email notifications covers templating and formatting techniques in detail.


    Handling the Finance Team Notification

    There's one step many people forget: Finance needs to know about approved expenses too. After the SharePoint update in the approved branch, add a second Send an email action addressed to your Finance team's shared mailbox or distribution list.

    This email should be more concise and data-focused than the submitter notification:

    To: finance-approvals@yourcompany.com

    Subject:

    [APPROVED] Expense for Processing — @{triggerOutputs()?['body/Title']} — $@{triggerOutputs()?['body/ExpenseAmount']}
    

    Body:

    Submitter: @{triggerOutputs()?['body/SubmitterEmail']}
    Approver: @{outputs('Get_manager_(V2)')?['body/displayName']}
    Category: @{triggerOutputs()?['body/ExpenseCategory/Value']}
    Amount: $@{triggerOutputs()?['body/ExpenseAmount']}
    Expense Date: @{triggerOutputs()?['body/ExpenseDate']}
    Receipt on File: @{triggerOutputs()?['body/ReceiptAttached']}
    SharePoint Record: https://yourcompany.sharepoint.com/sites/Finance/Lists/ExpenseSubmissions/DispForm.aspx?ID=@{triggerOutputs()?['body/ID']}
    

    That SharePoint link at the bottom means Finance can click through to the full record, see the attached receipt, and confirm the data — all from one email.


    Testing the Flow End to End

    Save your flow and do a real test, not just a dry run. Create a new list item in ExpenseSubmissions using an email address you can send approval requests to (temporarily use your own as the submitter email, and make sure your manager is set in Azure AD, or use a colleague who's volunteered to test).

    What to verify at each stage:

    1. Trigger fires: Check the flow run history within 60 seconds of creating the item. You should see the flow move to Running.

    2. Manager resolution: Expand the "Get manager" action in the run. Confirm the returned email and display name match the expected manager.

    3. Approval email received: The manager (or your test account) should receive an email from approvals@microsoft.com within a few minutes. Check that the dollar amount, category, and justification all appear correctly. Verify the Approve and Reject buttons are clickable.

    4. Approve the request: Click Approve in the email (you can add an optional comment). Within seconds, the flow should resume.

    5. SharePoint item updated: Refresh the list item. ApprovalStatus should show Approved, ApprovedDate should be populated, and ApprovalComments should show whatever you typed.

    6. Submitter notification received: Check the inbox for the submitter email address.

    Warning

    If you're testing with your own email as both submitter and approver, the approval request will arrive in your inbox from yourself. This can be confusing to debug — the flow is working correctly, it just looks odd. Use a second test account as the submitter if possible.

    If anything looks wrong, the Power Automate Run History and Flow Checker guide walks through the diagnostic tools in detail. The most common issue at this stage is an expression error in the approval details field — open the failed action in run history and read the error message carefully before changing anything.


    Hands-On Exercise

    Build the complete flow described in this lesson in your own environment. Then extend it with the following enhancements:

    Exercise 1 — Add a threshold condition

    Modify the flow so that expenses under $100 are auto-approved without manager involvement: the SharePoint item gets updated to Approved, the submitter gets notified, and Finance gets their email — but no approval request is sent. Add a Condition action after the trigger and before the "Get manager" step. If ExpenseAmount is less than 100, branch directly to the update/notify steps. Only expenses $100 or above route to the manager.

    This kind of threshold-based routing is a natural evolution of single-approver flows — the dynamic multi-condition approval flow guide covers more sophisticated routing rules when you're ready.

    Exercise 2 — Add a timeout escalation

    The "Start and wait for an approval" action has a Wait for duration setting. Set it to 48 hours. Then, after the action, add a Condition that checks whether the outcome is empty (the approval timed out rather than receiving a response). If timed out, update the status to "Escalated" and send a reminder email to the manager with a sharper subject line.

    Exercise 3 — Capture the form via Microsoft Forms

    Instead of users creating SharePoint list items directly, build a Microsoft Forms survey that collects the same expense data. Create a second flow triggered by the Forms response that creates the SharePoint list item, then let your existing approval flow take over from there. This is a common real-world pattern — Forms gives you a cleaner submission UX than a SharePoint list new item form. The Microsoft Forms automation guide covers exactly this pattern.


    Common Mistakes & Troubleshooting

    The approval email shows "[object Object]" for category or status fields

    You're referencing a Choice column without the /Value suffix. Every Choice column in SharePoint returns a JSON object. Use triggerOutputs()?['body/ExpenseCategory/Value'] instead of triggerOutputs()?['body/ExpenseCategory']. The same applies to Person columns (use /Email or /DisplayName).

    The "Get manager" action fails with "Resource not found"

    This usually means the email address passed in the User (UPN) field doesn't exist in Azure AD, or the account hasn't had a manager assigned. Verify by opening the Office 365 People search and looking up the user. If the manager field is blank in AD, the action will fail. Add an error handler (a parallel branch set to run on failure) that updates the ApprovalStatus to "Error - No Manager Found" and notifies the submitter.

    The flow trigger fires multiple times for the same item

    This happens if something is editing the list item at creation (a Power Apps form, another flow, a list validation rule). Consider switching the trigger to "When an item is created or modified" and adding a Condition at the top that checks ApprovalStatus equals Pending before proceeding — this prevents re-triggering on items that already have an outcome.

    Comments field is null even though the approver left a comment

    Check the approval action version. In older versions, comments live at body/responses/0/comments. In newer versions, the path may differ slightly. Always verify the actual response structure in your run history by expanding the approval action's raw output. Use first(outputs('Start_and_wait_for_an_approval')?['body/responses'])?['comments'] as a safer expression — first() handles the array gracefully.

    The flow runs but the SharePoint update doesn't reflect the change

    Double-check that the Id field in the Update Item action is using the integer ID from the trigger, not the GUID or any other identifier. SharePoint's Update item action requires the numeric item ID. Also confirm that the account running the flow has Edit permissions on the list (not just Read).

    Tip

    If you can't figure out why an expression is producing unexpected output, add a Compose action immediately after the problem step, put the expression in the Compose inputs, and check the run history. You'll see exactly what the expression evaluates to without breaking the rest of the flow.

    The approver never receives the email

    Check the manager's mailbox junk folder first — approval emails from approvals@microsoft.com occasionally get filtered. If that's not the issue, verify the email address in varManagerEmail by checking the run history for that Initialize variable step. Also confirm your tenant's Exchange policies don't block external senders (approval emails come from Microsoft's infrastructure, not your domain).


    Summary & Next Steps

    You've built a complete, production-ready expense approval workflow. Let's recap what it does: it triggers the moment a new expense is submitted to SharePoint, resolves the submitter's manager from Azure AD, sends a rich approval request the manager can action from their email, waits durably for the response, writes the outcome and comments back to the SharePoint record, and notifies both the submitter and Finance team. That entire paper trail — who submitted, who approved, when, and why — lives in your SharePoint list.

    This pattern is genuinely reusable. The same architecture handles purchase request approvals, PTO requests, vendor onboarding forms, and any other process where someone submits something and a human must decide on it.

    Where to go from here:

    • Multi-stage approvals: If your organization requires both a direct manager approval and a VP approval above a certain dollar threshold, the multi-stage approval chains guide covers sequential and parallel sign-off patterns built on top of this foundation.

    • Adaptive Card approvals in Teams: If your managers live in Teams more than email, implementing Adaptive Card approvals lets them approve directly from a Teams message with a richer interactive interface than email.

    • SLA enforcement and escalation: If you need approvals completed within a business-day window, time-sensitive approval escalations with Do Until loops gives you the timeout and escalation mechanics to enforce SLAs automatically.

    • Chaining connectors across M365: Once you're comfortable with this flow, the natural next step is enriching it — creating a Planner task for Finance when approved, posting a summary to a Teams channel, or adding a calendar event. Chaining Microsoft 365 connectors covers exactly that multi-connector choreography.

    The expense approval flow you built today isn't just an automation exercise — it's the kind of concrete, working artifact you can show stakeholders to demonstrate that Power Automate is production-ready for real business processes.

    Work With Us

    From insight to implementation

    Reading is the start. When you're ready to build the data, automation, or AI systems behind it, our team turns strategy into shipped results.

    Let's Build

    Flow Automation Basics

    Previous

    Automating a Microsoft Forms Approval Request with Power Automate: Capturing Responses, Routing to an Approver, and Sending Outcome Notifications

    Related Insights

    Power AutomateFoundation

    Implementing Power Automate Environment-Level Connector Allowlists and Tenant Isolation Policies

    18 min
    Power AutomateFoundation

    Connecting Power Automate Desktop to REST APIs with the HTTP Actions: Sending Requests, Parsing JSON Responses, and Writing Results to Excel

    17 min
    Power AutomateFoundation

    Automating a Microsoft Forms Approval Request with Power Automate: Capturing Responses, Routing to an Approver, and Sending Outcome Notifications

    17 min

    On this page

    • Introduction
    • Prerequisites
    • Designing the SharePoint List
    • Structuring the Flow: A Bird's-Eye View
    • Building the Trigger and Initial Data Steps
    • Getting the Manager
    • Initialize a Variable for the Manager Email
    • Sending the Approval Request
    • Branching on the Approval Outcome
    • Writing the Outcome Back to SharePoint
    • In the Yes (Approved) Branch
    • In the No (Rejected) Branch
    • Sending Outcome Notifications to the Submitter
    • Approved notification:
    • Rejected notification:
    • Handling the Finance Team Notification
    • Testing the Flow End to End
    • Hands-On Exercise
    • Common Mistakes & Troubleshooting
    • The approval email shows "[object Object]" for category or status fields
    • The "Get manager" action fails with "Resource not found"
    • The flow trigger fires multiple times for the same item
    • Comments field is null even though the approver left a comment
    • The flow runs but the SharePoint update doesn't reflect the change
    • The approver never receives the email
    • Summary & Next Steps