A legal team I worked with turned on content approval for their contracts library and then waited. Files sat in Pending for days, because nobody knew a review was needed. The approvers never got a single email.
That’s the gap most people miss. SharePoint content approval only changes a status column and hides the file from regular readers. It doesn’t notify anyone, and it doesn’t tell the author what happened. Power Automate has to do that part.
In this tutorial, we’ll build a SharePoint document approval workflow in Power Automate: turn on content approval, trigger only on Pending files, send the request to one or more approvers, set the file to Approved or Rejected, and email the author. I’ll also cover multiple approvers, common errors, and when SharePoint’s built-in Approvals is enough.
Quick answer: Turn on Require content approval for submitted items in the library’s Versioning settings. Then build an automated cloud flow: When a file is created or modified (properties only) with the trigger condition @equals(triggerOutputs()?['body/{ModerationStatus}'],'Pending') -> Get file metadata (for the ETag) -> Start and wait for an approval -> a Condition on the outcome -> Set content approval status (Approve or Reject, with the ETag) -> an email to the author.
What content approval does (and why it stays silent)
Content approval is a library setting. When it’s on, every file gets an Approval Status column (internal name _ModerationStatus) with a value such as Draft, Pending, Approved or Rejected. I explain the setting on its own in content approval in SharePoint Online; here we automate it.
While a file is Pending, regular readers keep seeing the last approved version, or nothing if the file is new. The Draft Item Security option decides who can see it: users who can read, users who can edit, or only approvers plus the author. Approvers need at least the Manage Lists permission level.
It works well for policies, contracts and published reports. The catch is that the status changes quietly, so approvers have to remember to check a filtered view. A flow fixes that by watching for Pending files and turning each one into an approval request. If you’re still planning the library itself, start with these SharePoint document library best practices.
The flow we’ll build is an automated cloud flow, which means it starts by itself when a file changes, unlike an instant flow (started by a button) or a scheduled flow (started by a timer).
Step 1: Turn on content approval for the document library
For this example I use a document library called Document Management Register. It starts empty:

Turn on content approval before you build anything, because the trigger condition reads the status it creates:
- Open the library, select the gear icon, and choose Library settings (then More library settings if you see the side panel).
- Under General Settings, select Versioning settings.
- Set Require content approval for submitted items? to Yes.
- Pick a Draft Item Security option. I use Only users who can approve items (and the author of the item) for contracts.
- Optional: choose Create major and minor (draft) versions if authors save drafts before submitting (see the note below).
- Select OK.

Important: files already in the library are marked Approved automatically when you turn this on, so nothing disappears. Only new uploads and edits go to Pending. You need Full Control or Design permission to change these settings.
Note: with major and minor versions on, a new upload is a Draft, not Pending. The author has to publish it as a major version (Submit for approval) before it becomes Pending, so the flow below starts at that moment. With major versions only, every upload goes straight to Pending.
I also tell business users up front that “approval” here only means hidden until someone changes the status. If this library is part of a larger SharePoint document management system, agree on who approves what before you switch it on.
Step 2: Add the When a file is created or modified (properties only) trigger
Go to Power Automate, select Create > Automated cloud flow, and pick the SharePoint trigger When a file is created or modified (properties only). You’ll find more SharePoint flows on the Power Automate tutorials hub.
I use the properties-only trigger because approval is a property change. An author can upload a contract today, get it rejected, fix it and resubmit tomorrow. The resubmission doesn’t create a new file, but it does change the Approval Status, and this trigger sees both cases.
- Site Address: your SharePoint site.
- Library Name: Document Management Register.
- Folder (advanced, optional): limit the flow to one folder, or leave it blank for the whole library.

Step 3: Add a trigger condition so the flow runs only for Pending files
Skip this step and you’ll regret it. Without a condition, the flow runs on every property change, including the change your own flow makes later when it sets the file to Approved. That’s a loop that eats your run quota.
Open the trigger, go to Settings, and under Trigger conditions select Add, then paste:
@equals(triggerOutputs()?['body/{ModerationStatus}'],'Pending')

In plain words: run only when the file’s approval status is Pending. When the flow later sets Approved or Rejected, the trigger fires again but the condition is false, so no run starts. The syntax is explained in Power Automate trigger conditions.
Step 4: Get the file’s ETag with Get file metadata
Add Get file metadata after the trigger and set File Identifier to the trigger’s Identifier value. Microsoft’s connector reference says Set content approval status needs an ETag for files and pages, and this action is the documented place to get it.

An ETag is a version stamp. If the file changes after you read it, SharePoint rejects an update that carries the old stamp. Never type or reuse one; pass the ETag from this action. When it goes wrong you’ll see the error covered in the ETag mismatch fix for content approval.
Pro Tip: if reviews can take days and authors keep editing, add a second Get file metadata right before Set content approval status and use its ETag. You’ll always send the newest stamp.
Step 5: Add Start and wait for an approval
This is the core of the flow. Add Start and wait for an approval and pick Approve/Reject – First to respond for a single sign-off. Fill in the fields like this:
- Title: the request name plus the file name (expression below).
- Assigned to: the approvers’ email addresses, separated by semicolons.
- Details: who submitted the file, when, and a link to open it.
Document Approval Request: @{triggerOutputs()?['body/{FilenameWithExtension}']}
A new document is waiting for your approval in the Document Management Register library.
Document name: @{triggerOutputs()?['body/{FilenameWithExtension}']}
Submitted by: @{triggerOutputs()?['body/Author/DisplayName']}
Submitted on: @{formatDateTime(convertFromUtc(triggerOutputs()?['body/Created'], 'Eastern Standard Time'), 'MM/dd/yyyy h:mm tt')} ET
Open the document: @{triggerOutputs()?['body/{Link}']}
Please review it and choose Approve or Reject.
Everything inside @{...} is dynamic content from the trigger. Created comes back in UTC, so I wrap it in convertFromUtc() and format it as MM/dd/yyyy; more patterns are in formatDateTime() in Power Automate. If tokens are new to you, read how Power Automate dynamic content works.
Two extras I often add: attach the document to the approval request so approvers can read it in Outlook, and custom approval responses such as Needs Revisions.
Also set an approval timeout with escalation, so a request doesn’t wait forever on someone who’s on vacation.
Multiple approvers: first to respond, everyone, or sequential
The approval type decides how many people must sign off. Same Document Management Register flow, only the dropdown changes:
| Approval type | What happens | Use it for |
|---|---|---|
| Approve/Reject – First to respond | Any one approver’s answer completes the request | One qualified reviewer is enough |
| Approve/Reject – Everyone must approve | Waits for all approvers; one rejection ends it | Contracts that need legal and finance |
| Sequential approval | One approver at a time, in the order you list | Manager first, then director |
| Custom Responses – Wait for one response | Your own buttons; any one answer completes it | Approve / Needs Revisions / Reject |
| Custom Responses – Wait for all responses | Your own buttons; everyone must answer | Document review sign-off by a panel |
With Everyone must approve, the outcome is Approve only when every person approves, so the Condition in Step 6 still works. I walk through the options in setting multiple approvers in Power Automate, and the ordered version in a sequential approval flow.
For rotating reviewers, send the approval to SharePoint group members instead of typing names, so the flow keeps working when the team changes.
With several approvers, responses[0] holds only the first answer. To collect every comment, add a Select action with From set to body('Start_and_wait_for_an_approval')?['responses'] and this Map value, then join the results for the email:
concat(item()?['responder']?['displayName'], ': ', item()?['comments'])
join(body('Select'), '<br>')
Step 6: Branch on the outcome and set the content approval status
Add a Condition. In the left box enter the outcome expression, choose is equal to, and type Approve in the right box:
outputs('Start_and_wait_for_an_approval')?['body/outcome']

If you need two tests at once, for example the outcome and a document type column, combine them as shown in Power Automate multiple conditions. With custom responses, compare the outcome with your own button label instead of Approve.
True branch: approve the document
In the True branch, add Set content approval status:
- Site Address and Library Name: the same as the trigger.
- Id: ID from the trigger.
- Action: Approve.
- Comments (advanced): the approver’s comment, expression below.
- ETag (advanced): ETag from Get file metadata.
body('Start_and_wait_for_an_approval')?['responses'][0]?['comments']

This action changes Approval Status to Approved, which makes the file visible to everyone who can read the library. The flow’s connection account must be allowed to approve items in that library. Then add Send an email (V2) to tell the author; you can also push a mobile notification if they live on their phone:
To: @{triggerOutputs()?['body/Author/Email']}
Subject: Your document "@{triggerOutputs()?['body/{FilenameWithExtension}']}" has been approved
Body:
Hello @{triggerOutputs()?['body/Author/DisplayName']},
Your document @{triggerOutputs()?['body/{FilenameWithExtension}']} in the Document Management Register library has been approved.
Approved on: @{formatDateTime(convertFromUtc(utcNow(), 'Eastern Standard Time'), 'MM/dd/yyyy h:mm tt')} ET
Comments: @{body('Start_and_wait_for_an_approval')?['responses'][0]?['comments']}

False branch: reject the document
Mirror both actions in the False branch. Set Action to Reject, keep the same comments and ETag, and change the email subject to say the document needs changes. Include the reviewer’s comment, because that’s the first thing the author will ask about.

Step 7: Test the document approval workflow
Test it the way a real author would, not with the Test button alone:
- Upload a file to Document Management Register (or edit and resubmit one). Its Approval Status shows Pending.
- Check that the approver gets the request in Outlook, Teams or the Power Automate Approvals center.
- Approve (or reject) it with a comment.
- Confirm the author’s email arrives with the comment, and the library shows Approved or Rejected.

Once the approver approved my test file, Doc3_Vendor_Invoice.pdf, the library showed Approved in the Approval Status column:

If a run fails, open its run history. Each action shows inputs and outputs, so you can see whether the trigger condition skipped the run or the ETag was rejected.
Built-in SharePoint Approvals vs this Power Automate flow
SharePoint lists and libraries now have their own Approvals feature: Configure Approvals > Enable Approvals, then Request approval on a file. It adds an Approval status column, supports one or all approvers, and approvers answer in the list or the Teams Approvals app. You can also send approvals to Microsoft Teams from a flow.
| Need | Built-in Approvals | This flow |
|---|---|---|
| Who starts the request | The author selects Request approval | Automatic when a file turns Pending |
| Hides the file until approved | No | Yes, through content approval |
| Custom emails, timeouts, routing | No | Yes |
| Setup | A few clicks in the library | A flow you build and test |
Microsoft notes that content approval isn’t integrated with the modern Approvals feature, so pick one per library. I use built-in Approvals for quick sign-offs and this flow when unapproved files must stay hidden.
Common errors and how to fix them
- The flow runs again and again: the trigger condition is missing or misspelled. Paste it exactly as shown in Step 3, including the curly braces around ModerationStatus.
- The flow never starts: content approval is off, or major and minor versions are on and the author never published the draft. The file must actually be Pending.
- ETag mismatch / “The resource has changed since the caller last read it”: the file changed after Get file metadata ran. Read the ETag right before Set content approval status.
- Access denied on Set content approval status: the connection account can’t approve items. Give it Design (or a level with Approve Items) on the library, or use a service account.
- Two approval requests for one file: the author edited a Pending file, which fires the trigger again. Ask authors not to edit a file while it’s in review, and reject the older request with a note if it happens.
- A failed update stalls silently: add a Scope with a configured run-after path, as in Power Automate exception handling with try and catch, and email the flow owner.
One more habit: build the flow under a service account. If it lives under a person’s account and that person leaves, the connection breaks and every document sits in Pending again.
If you’re building more approval processes next, these walkthroughs pick up where this one ends:
Frequently Asked Questions
Why doesn’t SharePoint send an email when content approval is turned on?
Content approval only sets the Approval Status column and controls who sees the file. It has no notification step, so you need a flow (or the built-in Approvals feature) to tell approvers and authors.
Can a SharePoint document approval workflow have multiple approvers?
Yes. In Start and wait for an approval, enter several emails and choose Everyone must approve (all must approve, one rejection ends it), First to respond (any one answer), or Sequential approval (one after another in order).
What value does the Set content approval status action expect?
Pick Approve or Reject in the Action field. Pass the file ID from the trigger and the ETag from Get file metadata, because files and pages require an ETag.
Can I use this flow as a document review workflow?
Yes. Use Custom Responses with buttons such as Approve, Needs Revisions and Reject, then add one Condition or Switch case per response. A Needs Revisions answer can email the author without changing the approval status.
Which approval types are available in Power Automate?
Microsoft lists Approve/Reject (Everyone must approve or First to respond), Custom Responses (wait for one or all) and Sequential approval in Get started with Power Automate approvals.

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.