Content moderation or page approval for modern SharePoint Online pages can be achieved by enabling and using the Flow > Configure page approval flow feature, accessible in the ribbon of the site pages library.

Using this option users can set up the approval flow for the site pages library of the current site, specifying a flow name and the user(s) that should moderate the publishing of new pages (or new versions).

You cannot user other type of entities for the approvers field, like “active directory security groups” or “Office 365 Groups”.

With this action, behind the scenes, a few things are setup:

  • The content moderation feature is enabled for the site pages library:
  • Two new views are added to the site pages library:
  • And two new fields are available to the library: “Approval Status” and “Approver Comments

After the completion of the setup of the approval flow, when a user submits a new page for approval, the flow will be triggered and the approval flow will handle the process. Pretty straightforward.

The configuration of the page approval flow is a manual process and needs to be done in each of the sites that we need to have this moderation control for the page publishing.

How to programmatically configure the page approval flow?

As far I could research, there is no available documentation of an API to programmatically configure the page approval flow in the site pages libraries. If you have any news on that please share it on the comments section!

I have mention previously what happens “under the hood” when we set up the approval flow using the “Configure page approval flow”.

The manual set up of the approval flow it’s pretty simple and it’s not an issue when we talk of a small number of sites. But if we have a big SharePoint intranet with dozens or even hundreds of sites? Things are not so simple.

Checking the HTTP requests that are performed when submitting the “create flow” action, we have some clues on what it’s happening:

It’s performed an HTTP post request with the following characteristics:

Some parts of endpoint address will depend on your environment, and you can check what’s yours using going to the Power Automate site > My flows.

The address will show your environment parameters

The request payload contains the parameters that will be used as the input’s for the provisioning of the template approval flow. The important ones are:

  • “parameters.sharepoint.approvers”:”
  • “”:”
  • “parameters.sharepoint.list”: “8901dcde-5e69-4063-9978-aca96845e127”

Those identify the approvers, the SharePoint site address and the identifier of the library.

Using a tool to analyze the authorization bearer token we can extract the audience of token.

Creating a script to automate the page approval flow provisioning

Enable the content approval setting for the desire library. I have used PnP PowerShell commands to connect to the desired SharePoint site and enable it on the library:

# Omitted some stuff like variables

Connect-PnPOnline -Url $siteUrl -Credentials $cred 
$list = Get-PnPList -Identity $listName
Set-PnPList -Identity $list.Id -EnableModeration $true 

Register an Azure AD Application – we need to be able to acquire a token that as access to use the Flow Service.

Add the “Flow.Manage.All” and “Flow.Read.All” permission scopes to the app. Don’t forget to set the grant permissions option with an admin account. Also, register the AppId and generate an AppSecret.

Acquire an authorization token through the registered app. I have done it in PowerShell.

Add-Type -AssemblyName System.Web 

$authUrl = "$tenantId/oauth2/token"
$resource = ""
$AppId = "xxxxxx"
$AppSecret = "xxxxxx"
$requestBody = @{
      client_id = $AppId
      client_secret = $AppSecret
      scope = 'openid'
      grant_type = 'password'
      username = $username
      password = $password
      resource = $resource
$body = @{
      ContentType = 'application/x-www-form-urlencoded'
      Method = 'POST'
      Body = $requestBody
      Uri = $authUrl
$Request = Invoke-RestMethod @body
$accessToken = $Request.access_token 

Now we should be able to perform the HTTP post request we need to create the approval flow:

# variables

$approvers = “;”

$headers = @{Authorization='Bearer ' + $accessToken;ContentType = "application/json"; Accept = "application/json" }

$endpointUrl = ""

# This is the request payload data we saw before. I have saved it to a local file for simplicity

$bodyFlowParams = Get-Content C:\Users\lribeiro\Desktop\createApprovalFlowDefinition.json | ConvertFrom-Json

# Update the payload parameters to have the correct site adress and list ID. For multiple approvers use the format user1@….com;user2…com

$bodyFlowParams.parameters.'' = $siteUrl 
$bodyFlowParams.parameters.'parameters.sharepoint.list' =  $list.Id
$bodyFlowParams.parameters.'parameters.sharepoint.approvers' = $approvers
$bodyFlowParams.displayName = "Page Approval Flow - " + (Get-PnPWeb).Title
$bodyFlowParams = $bodyFlowParams | ConvertTo-Json 

# Invoke the HTTP post request
$response = Invoke-WebRequest -Uri $endpointUrl -Method POST -Headers $headers -Body $bodyFlowParams -ContentType "application/json" -UseBasicParsing

$newFlowId = (($response | ConvertFrom-Json)"/")

#this is the new flow ID
$newFlowId = $newFlowId[$newFlowId.Length-1] 

This will create a new flow instance with the specified name:

And page approval flow will be enabled on the page submission approval flow option:

This approach creates a page approval flow based on the default page approval flow template. It’s possible to extend this solution and update the new flow with a different flow definition, based on a custom approval flow that meets the client business requirements.

If you know other ways of programmatically enable the page approval in SharePoint Online please leave a comment here!


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.