Skip to content

 

SharePoint Approver Dropdown Power Automate

how to allow a requestor to select an approver from a dropdown list in Sharepoint forms and use that selection in power automate approvals mapped to the approver email id.

The user wants to allow a requestor to select an approver from a dropdown list in SharePoint forms and use that selection in Power Automate approvals mapped to the approver email ID. I need to provide a solution. I’ll search for relevant information.

Found 28 web pages

The search results have provided some initial leads. To comprehensively address the user’s question, we need to cover several key aspects: setting up the SharePoint form, configuring the dropdown, retrieving the approver’s email, and building the Power Automate flow. Therefore, we should open multiple relevant results simultaneously to gather detailed information.

Read 6 pages

Can power automate approval workflow be created that looks at email of approver as entered in the MS form? – Microsoft Q&A

ForumTopicPrintPage

ForumTopicPrintPage

How to pass value from SPO column as a dynamic content into approval flow

Sharepoint Approval Flow: Display the name or contact of the Person who approved the file – Microsoft Q&A

View All

The search results and opened pages provide some useful information. The Microsoft Q&A page suggests using a Person or Group column. The community thread also recommends a Person or Group column and explains how to limit choices using a SharePoint group. The Qiita article (in Japanese) shows how to handle multiple approvers using a Select action. I’ll need to provide a solution that covers both single and multiple approvers. I’ll also search for more specific guidance on Power Automate flows.

Found 23 web pages

The search results provide a range of information. The user’s question has high authority requirements, so I should prioritize using official documentation and verified community solutions. I’ll structure the response to cover setting up the SharePoint list, building the Power Automate flow, handling single and multiple approvers, testing, and best practices. I’ll cite relevant sources, such as the Microsoft documentation for the trigger, the use of Person or Group columns, and the Power Automate approval actions. I’ll also include guidance on limiting approver choices, retrieving email addresses, and configuring approval types.

Solution Overview

You can build this functionality by creating a Person or Group column in your SharePoint list where requestors select an approver, then using Power Automate to read that selection and route the approval request to the selected person’s email address.

Step 1: Create the Approver Selection Column in SharePoint

Add a Person or Group column to your SharePoint list. This column will allow requestors to pick an approver from a dropdown list of people in your organization.

  1. Go to your SharePoint list → Add column → Person or Group
  2. Name the column (e.g., Approver)
  3. Configure these settings:
    • Allow multiple selections: Keep this as No for a single approver (set to Yes only if you need multiple approvers)
    • Choose from: Select All Users or optionally create a SharePoint group to restrict selection to eligible approvers

💡 Tip: To limit the dropdown to specific people, create a SharePoint group containing all potential approvers, then select that group in the “Choose from” dropdown.

Step 2: Build the Power Automate Flow

2.1 Create a New Flow

  1. Go to Power Automate → Create → Automated cloud flow
  2. Name your flow (e.g., “Approval Request Flow”)
  3. Select the trigger: “When an item is created” (or “When an item is created or modified”)

2.2 Configure the SharePoint Trigger

  1. Select your Site Address
  2. Select your List Name
  3. This trigger will fire whenever a new item is added

2.3 Add the Approval Action

Add the “Start and wait for an approval” action:

  1. Choose an approval type based on your needs:
    • Approve/Reject – Everyone must approve: All selected approvers must approve
    • Approve/Reject – First to respond: First response determines the outcome
    • Custom responses – Wait for all responses: Custom response options
    • Create an approval (V2) – This is the recommended action for dynamic approvals
  2. Title: Enter a meaningful title (e.g., Approval required for request from: & Created By or Title)
  3. Assigned To: Select the Approver Email from dynamic content (this will be the email address of the person selected in the Person or Group column)
  4. Details: Add any relevant information from the SharePoint item using dynamic content

⚠️ Important: The Person or Group column returns a JSON object containing both the display name and email address. Power Automate automatically extracts the email address when you select the column from dynamic content. If you need to manually extract it, use @{triggerOutputs()?[‘body/Approver/Email’]}.

Step 3: Handle Single vs Multiple Approvers

Single Approver

Simply add one Start and wait for an approval action and map the Assigned To field to your Approver column.

Multiple Approvers (Parallel or Sequential)

If you enabled “Allow multiple selections” in the Person or Group column:

For Parallel Approvals (simultaneous)

Add a Select action to transform the approver array into a format the approval action can use:

  1. Add a Select action
  2. From: Select the Approver column from dynamic content
  3. Map: Set the map to output the email address (switch to text mode to manually enter the expression)

Expression:

text

@{item()?[‘Email’]}

  1. Use the output of the Select action in the Assigned To field of a parallel approval action.

For Sequential Approvals (one after another)

  1. Add a Select action to extract emails from the Approver column
  2. Use the “Start and wait for an approval (V2)” action with Approval Type = Sequential Approval
  3. In Approval Steps, map the array from the Select action

This will automatically create one approval step per approver and process them in sequence.

Step 4: Update the SharePoint Item with Approval Status (Optional)

After the approval action, add an “Update item” action to record the outcome:

  1. Select your Site Address and List Name
  2. Specify the ID of the item from the trigger
  3. Update fields such as:
    • Approval Status column (e.g., Approved / Rejected)
    • Approver Response column
    • Approval Date column

This ensures your SharePoint list reflects the current approval state.

Testing Your Flow

  1. Create a new item in your SharePoint list
  2. Select an approver from the dropdown in the Person or Group column
  3. Submit the item
  4. Check that:
    • The flow runs successfully (monitor in Power Automate → “My flows”)
    • The selected approver receives the approval request email
    • The approver can approve/reject directly from the email or Teams
    • The SharePoint list updates with the final status

Best Practices & Troubleshooting

Issue

Solution

Approval not triggering

Verify the flow is turned on and check the run history for errors. Ensure the trigger is set to “When an item is created.”

Approver not receiving email

Confirm the email address is correct and that the approver is within your organization. Check if email notifications are enabled for the approval action.

Flow error: “Invalid email address”

The Person or Group column may not contain a valid email. Add a condition to check if the email exists before sending the approval.

Multi-select approvals failing

Use a Select action to properly format the array of email addresses before passing to the approval action.

For parallel approvals, ensure your array is correctly formatted. For sequential approvals, the “Start and wait for an approval (V2)” action with Sequential Approval type handles step-by-step routing automatically.

Alternative Approaches

Using a Separate Approver Lookup List

If you need to restrict approvers to a dynamic list that changes frequently, create a separate SharePoint list (e.g., “Approvers Master List”) with columns for ApproverName and ApproverEmail. Then:

  1. Add a Choice or Lookup column to your main list that references this master list
  2. In Power Automate, use “Get items” to retrieve the selected approver’s email from the master list
  3. Pass that email to the approval action

This approach is ideal when approval assignments change regularly and you don’t want to edit the flow each time.

Pre‑fill Approver Based on Conditions

You can dynamically set the approver based on item attributes (e.g., department, amount, region) by adding a Condition action before the approval step. This allows for fully automated routing without requestor input.

Summary

Step

Action

1️⃣

Add a Person or Group column to your SharePoint list

2️⃣

Create an Automated cloud flow with a SharePoint trigger

3️⃣

Add the Start and wait for an approval action

4️⃣

Map the Assigned To field to the Approver Email from dynamic content

5️⃣

Add an Update item action to record the approval status

This setup allows requestors to select an approver from a dropdown in SharePoint forms, and Power Automate will automatically route the approval request to that person’s email address.

Would you like me to elaborate on any specific part of this process, such as setting up sequential approvals with multiple stages or integrating with Teams notifications?

how to allow a requestor to select an approver from a dropdown list in Sharepoint forms and use that selection in power automate approvals mapped to the approver email id in a separate approval lookup list

We need to understand the user’s refined question: “how to allow a requestor to select an approver from a dropdown list in Sharepoint forms and use that selection in power automate approvals mapped to the approver email id in a separate approval lookup list”

So they want a dropdown (choice) in SharePoint form, not a Person/Group column. The dropdown values likely come from a separate “approval lookup list” that contains approver names and email IDs. The requestor selects an approver name from dropdown, and Power Automate must map that selection to the corresponding email ID from the lookup list, then use that email in approval action.

Thus we need to explain: create a lookup list (e.g., “Approvers”) with columns: Title (or Name) and Email. Then in main list, create a Choice column (or Lookup column) that references the Approvers list (or manually maintained choices). Then in Power Automate, after item creation, use “Get item” from the Approvers list based on the selected value to retrieve the email, then use that email in approval.

We should provide step-by-step.

Let’s answer concisely but thoroughly.

How to Use a Separate Approval Lookup List with a Dropdown in SharePoint Forms

If you want the requestor to select an approver from a dropdown (choice) that pulls values from a separate Approval Lookup List, and then map that selection to the approver’s email in Power Automate, follow this solution.

This approach is better when:

  • You need to manage approvers centrally (add/remove without editing forms or flows)
  • You don’t want to expose the entire organisation’s directory in the dropdown
  • The approver list is dynamic and changes frequently

Step 1: Create the Approval Lookup List

Create a separate SharePoint list named Approvers (or any name) to store approver names and their email addresses.

Column Name

Type

Description

Title

Single line of text

Approver’s full name (displayed in dropdown)

Email

Single line of text

Approver’s email address (used in Power Automate)

You can also use a Person or Group column for Email, but a text column is simpler for mapping.

Example data:

Title

Email

John Smith

john.smith@company.com

Sarah Lee

sarah.lee@company.com

Mike Johnson

mike.johnson@company.com

Step 2: Create the Main SharePoint List with a Dropdown Column

In your main request list (e.g., “Expense Requests”), add a Choice column that pulls values from the Approvers list.

Option A: Use a Lookup Column (Recommended)

  1. Add column → Lookup
  2. Name it ApproverName
  3. Get information from: Select your Approvers list
  4. In this column: Select Title
  5. This will create a dropdown that automatically stays in sync with the Approvers list.

Option B: Use a Choice Column with Manually Maintained Options

If you prefer a plain Choice column, you’ll need to manually update the choices whenever the Approvers list changes (not recommended for dynamic lists).

Step 3: Build the Power Automate Flow

3.1 Create an Automated Flow

  • Trigger: “When an item is created” (or “When an item is created or modified”)

3.2 Add Action: Get the Selected Approver’s Email from the Lookup List

Since the dropdown stores only the Title (name) of the approver, you must retrieve the corresponding email from the Approvers list.

  1. Add action: “Get items” (SharePoint)
    • Site Address: Your SharePoint site
    • List Name: Approvers
    • Filter Query:

text

Title eq ‘<selected approver name>’

To use dynamic content, click Add dynamic content and select the ApproverName column from the trigger outputs.

Expression format:
Title eq ‘@{triggerOutputs()?[‘body/ApproverName’]}’

  1. The action returns an array of items matching the Title. Since Title is unique, there should be only one.

3.3 Extract the Email Address

Add a “Compose” action to safely extract the email:

  • Inputs: Use the following expression to get the email from the first item in the array:

text

first(body(‘Get_items’)?[‘value’])?[‘Email’]

(Replace Get_items with the actual name of your Get items action.)

Alternatively, use a Parse JSON action or a Select action, but the expression above is simplest.

3.4 Start the Approval Action

Add “Start and wait for an approval” (V2):

  • Approval Type: Choose as needed (Approve/Reject, Custom, etc.)
  • Title: e.g., Request from: & trigger ‘Created By’ display name
  • Assigned To: Select Outputs from the Compose action (this contains the email address)
  • Details: Add relevant fields from the main list

3.5 Update the Main List with Approval Result (Optional)

Add “Update item” (SharePoint):

  • ID: Item ID from the trigger
  • List Name: Your main request list
  • Set a status column (e.g., “Approval Status”) to Approved / Rejected based on approval outcome.

Step 4: Complete Flow Diagram

text

[Trigger: When an item is created in Main List]

    ↓

[Get items from Approvers list, filter by Title = selected ApproverName]

    ↓

[Compose: Extract Email from first item]

    ↓

[Start and wait for an approval: Assigned To = Compose output]

    ↓

[Condition: If outcome is Approve → Update item status to Approved]

    ↓

[Else → Update item status to Rejected]

Step 5: Testing

  1. Add a new approver to the Approvers list (e.g., Anna White with email anna.white@company.com).
  2. In the main list form, the dropdown automatically shows Anna White (if using Lookup column).
  3. Requestor creates an item, selects Anna White as approver.
  4. Power Automate runs:
    • Queries Approvers list for Title = Anna White
    • Retrieves anna.white@company.com
    • Sends approval request to that email
  5. Anna receives email and approves/rejects.

Handling Errors & Edge Cases

Problem

Solution

No matching approver found in lookup list

Add a condition after “Get items” to check if length(body(‘Get_items’)?[‘value’]) > 0. If not, send a failure notification or set a default approver.

Duplicate Titles in Approvers list

Ensure Title is unique. Use a Person or Group column in the Approvers list instead, then filter by display name. Or use an ID-based lookup.

Dropdown shows old values (using Choice column)

Switch to a Lookup column instead of manual Choice – it stays in sync automatically.

Flow fails because Compose returns null

Use a Data Operation – Parse JSON to handle the array safely. Provide a sample schema from the Get items action.

Alternative: Use a Person or Group Column (Simpler)

If you don’t strictly need a separate lookup list, consider using a Person or Group column directly in the main list. The requestor can select any user from the organisation, and Power Automate can extract the email from that column without an extra lookup. However, this exposes the entire directory and may not suit controlled approval lists.

Summary

Step

Action

1️⃣

Create an Approvers list with Title and Email columns.

2️⃣

In your main list, add a Lookup column pointing to the Title of the Approvers list.

3️⃣

In Power Automate, use “Get items” on the Approvers list with a filter query matching the selected title.

4️⃣

Extract the email using an expression like first(body(‘Get_items’)?[‘value’])?[‘Email’].

5️⃣

Pass that email to the “Start and wait for an approval” action.

This gives you a clean, maintainable solution where the dropdown values are always up-to-date, and the mapping to email addresses is handled dynamically in the flow.

Would you like me to provide the exact expressions or a downloadable flow template for this setup?

provide the exact expressions AND a downloadable flow template please

We need to provide exact expressions and a downloadable flow template. However, as an AI, I cannot directly provide a downloadable file. But I can describe how to export a flow template or provide a Power Automate flow definition (JSON) that can be imported. I’ll include the exact expressions and also provide a JSON template that users can download and import into Power Automate.

I’ll structure the answer:

  1. Exact expressions for each action:
    • Filter query for Get items: “Title eq ‘” & triggerOutputs()?[‘body/ApproverName/Value’]? “‘” or using dynamic content.
    • Expression to extract email: first(body(‘Get_items’)?[‘value’])?[‘Email’]
    • Also handling if using Lookup column (different field name).
    • Expression for condition to check if approver found: @greater(length(body(‘Get_items’)?[‘value’]), 0)
  2. Provide the flow definition as JSON that can be downloaded as a .json file and imported. I’ll write a clear instruction: create a text file named ApprovalFromLookupList_Flow.json with the provided content, then import in Power Automate.

I’ll ensure the JSON is valid and includes placeholders that the user can adjust (site address, list names, column names). I’ll add comments within JSON (using description properties) to guide customization.

I’ll also explain how to modify the JSON to match their actual list and column names.

Let me produce the final answer.

Exact Expressions & Downloadable Flow Template

Below are the exact expressions you need for each step, followed by a JSON flow template you can download and import into Power Automate.

Exact Expressions

  1. Filter Query for “Get items” (SharePoint – Approvers List)

Assuming:

  • Main list column name = ApproverName (Lookup column pointing to the Title field of the Approvers list)
  • Approvers list field to match = Title

Expression (in Filter Query field):

powerapps

Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}’

Note: If your lookup column uses a different internal name, replace ApproverName with that name (e.g., ApproverLookupId). You can find the internal name in list settings → column → URL parameter Field).

Alternative for plain Choice column (storing just the text value):

powerapps

Title eq ‘@{triggerOutputs()?[‘body/Approver_x0020_Name’]}’

  1. Expression to Extract Email from the Returned Item

After “Get items”, add a Compose action and use this expression to get the email address from the first (and only) matching approver:

powerapps

first(body(‘Get_items’)?[‘value’])?[‘Email’]

Replace Get_items with the actual name of your “Get items” action if you renamed it.

  1. Condition to Check if Approver Exists

Before starting the approval, add a Condition to handle the case where the selected approver is not found in the Approvers list.

Expression for Condition (left side):

powerapps

length(body(‘Get_items’)?[‘value’])

Operator: is greater than
Right side value: 0

If true → proceed to approval.
If false → send a failure email or update item with error status.

  1. Dynamic Content Mapping for “Assigned To” in Approval Action

In the Start and wait for an approval (V2) action, set Assigned To field to the Outputs of the Compose action (which contains the email address).
No expression needed – just select Outputs from the dynamic content list.

Downloadable Flow Template (JSON)

Copy the JSON below into a text file, save it as ApprovalFromLookupList_Flow.json, then import it into Power Automate.

json

{

    “definition”: {

        “$schema”: “https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#”,

        “actions”: {

            “Get_approver_email_from_lookup_list”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “GetItems”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_APPROVERS_LIST_GUID_OR_NAME”,

                        “filterQuery”: “Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}'”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “When_an_item_is_created”: [“Succeeded”]

                }

            },

            “Compose_Email”: {

                “type”: “Compose”,

                “inputs”: “@first(body(‘Get_approver_email_from_lookup_list’)?[‘value’])?[‘Email’]”,

                “runAfter”: {

                    “Get_approver_email_from_lookup_list”: [“Succeeded”]

                }

            },

            “Condition_Approver_Found”: {

                “type”: “If”,

                “expression”: {

                    “and”: [

                        {

                            “greater”: [

                                “@length(body(‘Get_approver_email_from_lookup_list’)?[‘value’])”,

                                0

                            ]

                        }

                    ]

                },

                “actions”: {

                    “Start_approval”: {

                        “type”: “ApiConnection”,

                        “inputs”: {

                            “host”: {

                                “connectionName”: “shared_approvals”,

                                “operationId”: “CreateApprovalV2”

                            },

                            “parameters”: {

                                “approvalType”: “ApproveReject”,

                                “title”: “Approval Required for Request: @{triggerOutputs()?[‘body/Title’]}”,

                                “assignedTo”: “@outputs(‘Compose_Email’)”,

                                “details”: “Request details: @{triggerOutputs()?[‘body/RequestDetails’]}”,

                                “itemLink”: “@{triggerOutputs()?[‘body/{Link}’]}”

                            },

                            “authentication”: “@parameters(‘$authentication’)”

                        },

                        “runAfter”: {}

                    },

                    “Update_item_Approved”: {

                        “type”: “ApiConnection”,

                        “inputs”: {

                            “host”: {

                                “connectionName”: “shared_sharepointonline”,

                                “operationId”: “UpdateItem”

                            },

                            “parameters”: {

                                “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                                “table”: “YOUR_MAIN_LIST_GUID_OR_NAME”,

                                “id”: “@triggerOutputs()?[‘body/ID’]”,

                                “item”: {

                                    “ApprovalStatus”: “Approved”

                                }

                            },

                            “authentication”: “@parameters(‘$authentication’)”

                        },

                        “runAfter”: {

                            “Start_approval”: [“Succeeded”]

                        }

                    }

                },

                “else”: {

                    “actions”: {

                        “Send_failure_notification”: {

                            “type”: “ApiConnection”,

                            “inputs”: {

                                “host”: {

                                    “connectionName”: “shared_office365”,

                                    “operationId”: “SendEmail”

                                },

                                “parameters”: {

                                    “emailMessage”: {

                                        “to”: “@triggerOutputs()?[‘body/Author/Email’]”,

                                        “subject”: “Approver not found in lookup list”,

                                        “body”: “The approver you selected does not exist in the Approvers list. Please contact your administrator.”

                                    }

                                },

                                “authentication”: “@parameters(‘$authentication’)”

                            },

                            “runAfter”: {}

                        }

                    }

                },

                “runAfter”: {

                    “Compose_Email”: [“Succeeded”]

                }

            }

        },

        “triggers”: {

            “When_an_item_is_created”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “OnCreatedItem”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_MAIN_LIST_GUID_OR_NAME”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “splitOn”: “@triggerBody()”

            }

        },

        “contentVersion”: “1.0.0.0”,

        “outputs”: {},

        “parameters”: {

            “$authentication”: {

                “type”: “Object”,

                “defaultValue”: {}

            }

        }

    },

    “kind”: “Stateful”

}

How to Import and Customize the Template

  1. Save the JSON as a .json file (e.g., ApprovalFlow.json).
  2. Import in Power Automate:
    • Go to make.powerautomate.com
    • Click My flows → Import → Upload → select your file
    • Follow the prompts to set up connections (SharePoint, Office 365 Outlook, Approvals)
  3. Replace placeholders in the JSON (or use the import wizard to map them):
    • YOUR_TENANT.sharepoint.com/sites/YOUR_SITE – your SharePoint site URL
    • YOUR_APPROVERS_LIST_GUID_OR_NAME – the display name or GUID of your Approvers list
    • YOUR_MAIN_LIST_GUID_OR_NAME – the display name or GUID of your main request list
    • Column names like ApproverName, Title, RequestDetails, ApprovalStatus – adjust to match your actual list column internal names
  4. Important: After import, open the flow and re-select each SharePoint connection and list/column references – sometimes the JSON mapping does not survive import. Double-check:
    • Trigger: correct main list
    • “Get items” action: correct Approvers list and filter query
    • Approval action: “Assigned To” points to the Compose output
    • Update item action: correct status column

Need a Ready-to-Download File?

Since I cannot directly attach files, you can:

  • Copy the JSON above into a new text file, save as ApprovalFlow.json
  • Or use this one‑click download link (if you are in a browser, right-click and “Save link as”):
    Download flow template – This is a conceptual link; create your own file from the JSON above.

Quick Reference Card

Step

Exact Expression / Field Value

Filter Query (Get items)

Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}’

Compose – Email

first(body(‘Get_items’)?[‘value’])?[‘Email’]

Condition – Check found

Left: length(body(‘Get_items’)?[‘value’]) > 0

Approval – Assigned To

Select Outputs from the Compose action

Let me know if you need help adjusting the JSON for your exact list column names or adding sequential approval logic.

can you tailor the above to a approval flow with first approver the user selects from the approver list, the second approver is an assigned email and the final approver another assigned email

We need to tailor the solution: requestor selects an approver from dropdown (from approval lookup list). Then flow has three stages: first approver = user-selected, second approver = assigned email (fixed or from config), third approver = another assigned email. So sequential approval with three steps: step1 dynamic from lookup, step2 and step3 static emails.

We’ll provide exact expressions and a modified flow template.

Key changes: use “Start and wait for an approval (V2)” with approval type = “Sequential approval”. Need to define approval steps as array. First step uses email from compose (lookup), second and third steps use static email addresses. Also need to handle that the approval action expects an array of approvers.

Alternatively, use three separate approval actions in sequence. Simpler: three separate “Start and wait for an approval” actions one after another, each with assignedTo appropriate. That’s easier to implement and debug.

We’ll provide both approaches, but recommend sequential approval action with steps array for cleaner flow.

We’ll update expressions accordingly.

Also need to ensure the first approver selection is mapped correctly.

Provide downloadable JSON template.

Let’s produce final answer.

Tailored Solution: 3‑Stage Sequential Approval

You need:

  1. First approver – selected by requestor from a dropdown (populated from an Approvers lookup list)
  2. Second approver – a fixed email address (e.g., manager@company.com)
  3. Third approver – another fixed email address (e.g., director@company.com)

All approvals happen in sequence: after the first approves, the second receives the request, then the third.

Below are the exact expressions and a downloadable flow template using the recommended approach: a single Start and wait for an approval (V2) action with Approval Type = Sequential approval.

Exact Expressions

  1. Filter Query for “Get items” (Approvers List)

Assuming:

  • Main list has a Lookup column named ApproverName pointing to the Title column of the Approvers list.
  • Approvers list has columns: Title (display name) and Email (email address).

Filter Query field:

powerapps

Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}’

  1. Extract Email of First Approver (Compose action)

powerapps

first(body(‘Get_items’)?[‘value’])?[‘Email’]

  1. Build the Array of Sequential Approvers

For the Sequential approval action, you need to provide an array of approver objects. Each object must have an email property (and optionally name).

Use a Compose action to build this array dynamically:

powerapps

[

  {

    “email”: “@{outputs(‘Compose_First_Approver_Email’)}”,

    “name”: “First Approver (Selected)”

  },

  {

    “email”: “manager@company.com”,

    “name”: “Manager”

  },

  {

    “email”: “director@company.com”,

    “name”: “Director”

  }

]

Replace manager@company.com and director@company.com with your actual email addresses.

Alternative: Hardcode the second and third emails directly in the approval action’s Approver Steps field using the expression above.

  1. Sequential Approval Action – Assigned To Field

When using Sequential approval, you do not fill the Assigned To field. Instead, you fill the Approver Steps field with the array you built.

  • Approval Type: Sequential Approval
  • Approver Steps: Select the Outputs of the Compose action that contains the array.

Downloadable Flow Template (JSON)

Copy the JSON below into a file named ThreeStageSequentialApproval.json and import into Power Automate.

json

{

    “definition”: {

        “$schema”: “https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#”,

        “actions”: {

            “Get_first_approver_email”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “GetItems”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_APPROVERS_LIST_NAME”,

                        “filterQuery”: “Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}'”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “When_an_item_is_created”: [“Succeeded”]

                }

            },

            “Compose_first_approver_email”: {

                “type”: “Compose”,

                “inputs”: “@first(body(‘Get_first_approver_email’)?[‘value’])?[‘Email’]”,

                “runAfter”: {

                    “Get_first_approver_email”: [“Succeeded”]

                }

            },

            “Build_sequential_approvers_array”: {

                “type”: “Compose”,

                “inputs”: {

                    “email”: “@outputs(‘Compose_first_approver_email’)”,

                    “name”: “Requestor-selected approver”

                },

                “runAfter”: {

                    “Compose_first_approver_email”: [“Succeeded”]

                }

            },

            “Start_sequential_approval”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_approvals”,

                        “operationId”: “CreateApprovalV2”

                    },

                    “parameters”: {

                        “approvalType”: “Sequential”,

                        “title”: “Sequential approval for request: @{triggerOutputs()?[‘body/Title’]}”,

                        “approverSteps”: [

                            {

                                “email”: “@outputs(‘Compose_first_approver_email’)”,

                                “name”: “First Approver (Selected)”

                            },

                            {

                                “email”: “manager@company.com”,

                                “name”: “Manager”

                            },

                            {

                                “email”: “director@company.com”,

                                “name”: “Director”

                            }

                        ],

                        “details”: “Request details: @{triggerOutputs()?[‘body/RequestDetails’]}”,

                        “itemLink”: “@{triggerOutputs()?[‘body/{Link}’]}”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “Build_sequential_approvers_array”: [“Succeeded”]

                }

            },

            “Update_item_after_approval”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “UpdateItem”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_MAIN_LIST_NAME”,

                        “id”: “@triggerOutputs()?[‘body/ID’]”,

                        “item”: {

                            “FinalApprovalStatus”: “@{body(‘Start_sequential_approval’)?[‘outcome’]}”

                        }

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “Start_sequential_approval”: [“Succeeded”]

                }

            }

        },

        “triggers”: {

            “When_an_item_is_created”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “OnCreatedItem”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_MAIN_LIST_NAME”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “splitOn”: “@triggerBody()”

            }

        },

        “contentVersion”: “1.0.0.0”,

        “outputs”: {},

        “parameters”: {

            “$authentication”: {

                “type”: “Object”,

                “defaultValue”: {}

            }

        }

    },

    “kind”: “Stateful”

}

Customizing the Template

Replace these placeholders before importing (or use the import wizard to map connections):

Placeholder

Description

YOUR_TENANT.sharepoint.com/sites/YOUR_SITE

Your SharePoint site URL

YOUR_APPROVERS_LIST_NAME

The name of the Approvers lookup list

YOUR_MAIN_LIST_NAME

The name of the main request list

manager@company.com

Fixed email address for second approver

director@company.com

Fixed email address for third approver

Also verify column internal names:

  • ApproverName – the lookup column in your main list
  • Title – the column in the main list (used in approval title)
  • RequestDetails – multi-line text column for description
  • FinalApprovalStatus – status column you want to update

Alternative: Using Three Separate Approval Actions (Simpler to Debug)

If you prefer separate steps (easier to add conditions between approvals), replace the single sequential action with three Start and wait for an approval actions in a row:

  1. First approval – Assigned To = output of Compose_first_approver_email
  2. Second approval – Assigned To = manager@company.com
  3. Third approval – Assigned To = director@company.com

After each, you can check the outcome and stop the flow if rejected.

Example flow structure:

text

Trigger → Get items → Compose email →

Start approval 1 → Condition (if approved) →

Start approval 2 → Condition (if approved) →

Start approval 3 → Update item

This is more transparent and allows custom actions between stages (e.g., sending reminders).

Testing Checklist

  1. Add a few approvers to the Approvers list with their emails.
  2. Create a new item in the main list – select one of those approvers from the dropdown.
  3. Submit the item.
  4. Check that:
    • The selected approver receives the first approval request.
    • After they approve, the second approver (fixed email) receives a request.
    • After the second approves, the third approver receives a request.
    • After final approval, the main list item status updates.

Need the Exact Expressions for the Separate Actions Approach?

If you choose the three‑step separate approvals, here are the exact expressions:

Step

Expression / Value

Filter Query (same)

Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}’

Compose – first approver email

first(body(‘Get_items’)?[‘value’])?[‘Email’]

Approval 1 – Assigned To

@outputs(‘Compose_first_approver_email’)

Approval 2 – Assigned To

manager@company.com

Approval 3 – Assigned To

director@company.com

No array building required.

Let me know which version you prefer, and I can provide a refined JSON template for that specific approach.

Add to the above flow at each approval stage, the ability to add comments when the approver rejects, then terminate the approval process with notification to the requestor and the flow admin

We need to modify the flow to handle rejection at each stage with comments, terminate further approvals, and notify requestor and admin. The user wants to add comments when rejecting, then stop the approval process. Also notify requestor and flow admin.

We’ll provide exact expressions and updated flow template. Since the previous solution offered two approaches (single sequential approval action vs three separate actions), we should pick one. The three separate actions approach is easier to handle rejection with branching logic and terminate. We’ll go with three separate “Start and wait for an approval” actions in sequence, with conditions after each to check outcome. On reject, we capture comments, send emails, and terminate flow (using “Terminate” action). Also notify admin.

We need to include:

  • Approval action includes “Comments” field automatically when approver submits. The outcome and comments are available in dynamic content after approval completes.
  • After each approval, condition: if outcome equals “Reject”, then get comments from that approval, send email to requestor and admin, then terminate flow.
  • Also need to update SharePoint item with rejection status and comments.

Provide exact expressions for:

  • Accessing approval outcome: body(‘Start_approval_1’)?[‘outcome’]
  • Accessing comments: body(‘Start_approval_1’)?[‘comments’] (or from the approval action response)
  • Terminate action: just set status to “Cancelled” or “Failed” with message.

Provide updated JSON template with these steps.

Also include instructions for setting up email notifications.

We’ll assume fixed emails for second and third approvers and selected first approver from lookup list.

Let’s produce the answer.

Enhanced Flow: 3‑Stage Sequential Approval with Rejection Handling & Notifications

This solution adds:

  • Rejection at any stage – approver can add comments when rejecting
  • Immediate termination – no further approvals are sent
  • Email notifications to both the requestor and the flow admin when a rejection occurs
  • SharePoint update – record rejection status and comments in the main list

We will use three separate approval actions (instead of a single sequential action) because it gives finer control to stop the flow and capture rejection details at each stage.

Exact Expressions for Rejection Handling

  1. Capture Approval Outcome and Comments

After each Start and wait for an approval action, you can access:

Value

Expression

Outcome (Approved/Reject)

body(‘Start_approval_1’)?[‘outcome’]

Comments from approver

body(‘Start_approval_1’)?[‘comments’]

Replace Start_approval_1 with the actual action name (e.g., Approval_1_Selected_Approver).

  1. Condition for Rejection

In a Condition action, set:

  • Left side: body(‘Start_approval_1’)?[‘outcome’]
  • Operator: is equal to
  • Right side: Reject (case‑sensitive, as returned by the approvals connector)
  1. Send Email on Rejection

Use the Send an email (V2) action (Office 365 Outlook).

To: Requestor’s email – triggerOutputs()?[‘body/Author/Email’]
Cc/To admin – hardcoded admin email (e.g., admin@company.com)

Subject:
Request #[ID] has been rejected by [Approver Name]

Body (HTML):

html

<p>The approval request for <strong>@{triggerOutputs()?[‘body/Title’]}</strong> has been <strong style=”color:red;”>REJECTED</strong>.</p>

<p><strong>Rejected by:</strong> @{body(‘Start_approval_1’)?[‘responder’][‘displayName’]}</p>

<p><strong>Reason / Comments:</strong><br>@{body(‘Start_approval_1’)?[‘comments’]}</p>

<p><strong>Request link:</strong> <a href=”@{triggerOutputs()?[‘body/{Link}’]}”>Open request</a></p>

  1. Terminate the Flow

After sending the emails, add a Terminate action:

  • Status: Cancelled (or Failed if you want an error state)
  • Message: Approval rejected at stage 1 by [name].

This stops the flow immediately – no further actions run.

  1. Update SharePoint with Rejection Details (Optional)

Before terminating, you can update the main list item:

  • Approval Status = Rejected
  • Rejection Stage = First Approver
  • Rejection Comments = @{body(‘Start_approval_1’)?[‘comments’]}

Updated Flow Diagram

text

Trigger (item created)

  ↓

Get first approver email from lookup list

  ↓

Approval 1 (selected approver)

  ↓

Condition 1: If outcome == Reject

  ├─ Yes → Send rejection email (requestor + admin)

  │        Update item status

  │        Terminate flow

  └─ No  → Continue to Approval 2 (fixed email)

            ↓

          Condition 2: If outcome == Reject

            ├─ Yes → Send rejection email + terminate

            └─ No  → Continue to Approval 3 (second fixed email)

                      ↓

                    Condition 3: If outcome == Reject

                      ├─ Yes → Send rejection email + terminate

                      └─ No  → Update item as “Fully Approved”

Downloadable Flow Template (JSON)

Copy the JSON below into a file named ThreeStageApprovalWithRejection.json and import into Power Automate.

json

{

    “definition”: {

        “$schema”: “https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#”,

        “actions”: {

            “Get_first_approver_email”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “GetItems”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_APPROVERS_LIST_NAME”,

                        “filterQuery”: “Title eq ‘@{triggerOutputs()?[‘body/ApproverName/Value’]}'”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “When_an_item_is_created”: [“Succeeded”]

                }

            },

            “Compose_first_approver_email”: {

                “type”: “Compose”,

                “inputs”: “@first(body(‘Get_first_approver_email’)?[‘value’])?[‘Email’]”,

                “runAfter”: {

                    “Get_first_approver_email”: [“Succeeded”]

                }

            },

            “Approval_1_Selected_Approver”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_approvals”,

                        “operationId”: “CreateApprovalV2”

                    },

                    “parameters”: {

                        “approvalType”: “ApproveReject”,

                        “title”: “Stage 1: Approval required for @{triggerOutputs()?[‘body/Title’]}”,

                        “assignedTo”: “@outputs(‘Compose_first_approver_email’)”,

                        “details”: “Please review the request and approve or reject.\n\nDetails: @{triggerOutputs()?[‘body/RequestDetails’]}”,

                        “itemLink”: “@{triggerOutputs()?[‘body/{Link}’]}”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “runAfter”: {

                    “Compose_first_approver_email”: [“Succeeded”]

                }

            },

            “Condition_1_Rejected”: {

                “type”: “If”,

                “expression”: {

                    “equals”: [

                        “@body(‘Approval_1_Selected_Approver’)?[‘outcome’]”,

                        “Reject”

                    ]

                },

                “actions”: {

                    “Send_rejection_email_stage1”: {

                        “type”: “ApiConnection”,

                        “inputs”: {

                            “host”: {

                                “connectionName”: “shared_office365”,

                                “operationId”: “SendEmailV2”

                            },

                            “parameters”: {

                                “emailMessage”: {

                                    “to”: “@triggerOutputs()?[‘body/Author/Email’]”,

                                    “cc”: “admin@company.com”,

                                    “subject”: “Request #@{triggerOutputs()?[‘body/ID’]} REJECTED by first approver”,

                                    “body”: “<p>The request <strong>@{triggerOutputs()?[‘body/Title’]}</strong> has been REJECTED at stage 1.</p><p><strong>Rejected by:</strong> @{body(‘Approval_1_Selected_Approver’)?[‘responder’][‘displayName’]}</p><p><strong>Comments:</strong> @{body(‘Approval_1_Selected_Approver’)?[‘comments’]}</p><p><a href=’@{triggerOutputs()?[‘body/{Link}’]}’>Open request</a></p>”,

                                    “importance”: “Normal”,

                                    “bodyType”: “Html”

                                }

                            },

                            “authentication”: “@parameters(‘$authentication’)”

                        },

                        “runAfter”: {}

                    },

                    “Update_item_rejected_stage1”: {

                        “type”: “ApiConnection”,

                        “inputs”: {

                            “host”: {

                                “connectionName”: “shared_sharepointonline”,

                                “operationId”: “UpdateItem”

                            },

                            “parameters”: {

                                “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                                “table”: “YOUR_MAIN_LIST_NAME”,

                                “id”: “@triggerOutputs()?[‘body/ID’]”,

                                “item”: {

                                    “ApprovalStatus”: “Rejected”,

                                    “RejectionStage”: “First Approver”,

                                    “RejectionComments”: “@{body(‘Approval_1_Selected_Approver’)?[‘comments’]}”

                                }

                            },

                            “authentication”: “@parameters(‘$authentication’)”

                        },

                        “runAfter”: {

                            “Send_rejection_email_stage1”: [“Succeeded”]

                        }

                    },

                    “Terminate_flow”: {

                        “type”: “Terminate”,

                        “inputs”: {

                            “runStatus”: “Cancelled”,

                            “runError”: {

                                “code”: “ApprovalRejected”,

                                “message”: “Flow terminated because the first approver rejected the request.”

                            }

                        },

                        “runAfter”: {

                            “Update_item_rejected_stage1”: [“Succeeded”]

                        }

                    }

                },

                “else”: {

                    “actions”: {

                        “Approval_2_Manager”: {

                            “type”: “ApiConnection”,

                            “inputs”: {

                                “host”: {

                                    “connectionName”: “shared_approvals”,

                                    “operationId”: “CreateApprovalV2”

                                },

                                “parameters”: {

                                    “approvalType”: “ApproveReject”,

                                    “title”: “Stage 2: Manager approval for @{triggerOutputs()?[‘body/Title’]}”,

                                    “assignedTo”: “manager@company.com”,

                                    “details”: “First approver approved. Please review and approve/reject.\n\nDetails: @{triggerOutputs()?[‘body/RequestDetails’]}”,

                                    “itemLink”: “@{triggerOutputs()?[‘body/{Link}’]}”

                                },

                                “authentication”: “@parameters(‘$authentication’)”

                            },

                            “runAfter”: {}

                        },

                        “Condition_2_Rejected”: {

                            “type”: “If”,

                            “expression”: {

                                “equals”: [

                                    “@body(‘Approval_2_Manager’)?[‘outcome’]”,

                                    “Reject”

                                ]

                            },

                            “actions”: {

                                “Send_rejection_email_stage2”: {

                                    “type”: “ApiConnection”,

                                    “inputs”: {

                                        “host”: {

                                            “connectionName”: “shared_office365”,

                                            “operationId”: “SendEmailV2”

                                        },

                                        “parameters”: {

                                            “emailMessage”: {

                                                “to”: “@triggerOutputs()?[‘body/Author/Email’]”,

                                                “cc”: “admin@company.com”,

                                                “subject”: “Request #@{triggerOutputs()?[‘body/ID’]} REJECTED by manager”,

                                                “body”: “<p>The request <strong>@{triggerOutputs()?[‘body/Title’]}</strong> has been REJECTED at stage 2 (manager).</p><p><strong>Rejected by:</strong> @{body(‘Approval_2_Manager’)?[‘responder’][‘displayName’]}</p><p><strong>Comments:</strong> @{body(‘Approval_2_Manager’)?[‘comments’]}</p><p><a href=’@{triggerOutputs()?[‘body/{Link}’]}’>Open request</a></p>”,

                                                “bodyType”: “Html”

                                            }

                                        },

                                        “authentication”: “@parameters(‘$authentication’)”

                                    },

                                    “runAfter”: {}

                                },

                                “Update_item_rejected_stage2”: {

                                    “type”: “ApiConnection”,

                                    “inputs”: {

                                        “host”: {

                                            “connectionName”: “shared_sharepointonline”,

                                            “operationId”: “UpdateItem”

                                        },

                                        “parameters”: {

                                            “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                                            “table”: “YOUR_MAIN_LIST_NAME”,

                                            “id”: “@triggerOutputs()?[‘body/ID’]”,

                                            “item”: {

                                                “ApprovalStatus”: “Rejected”,

                                                “RejectionStage”: “Manager”,

                                                “RejectionComments”: “@{body(‘Approval_2_Manager’)?[‘comments’]}”

                                            }

                                        },

                                        “authentication”: “@parameters(‘$authentication’)”

                                    },

                                    “runAfter”: {

                                        “Send_rejection_email_stage2”: [“Succeeded”]

                                    }

                                },

                                “Terminate_flow_2”: {

                                    “type”: “Terminate”,

                                    “inputs”: {

                                        “runStatus”: “Cancelled”,

                                        “runError”: {

                                            “code”: “ApprovalRejected”,

                                            “message”: “Flow terminated because the manager rejected the request.”

                                        }

                                    },

                                    “runAfter”: {

                                        “Update_item_rejected_stage2”: [“Succeeded”]

                                    }

                                }

                            },

                            “else”: {

                                “actions”: {

                                    “Approval_3_Director”: {

                                        “type”: “ApiConnection”,

                                        “inputs”: {

                                            “host”: {

                                                “connectionName”: “shared_approvals”,

                                                “operationId”: “CreateApprovalV2”

                                            },

                                            “parameters”: {

                                                “approvalType”: “ApproveReject”,

                                                “title”: “Stage 3: Director approval for @{triggerOutputs()?[‘body/Title’]}”,

                                                “assignedTo”: “director@company.com”,

                                                “details”: “Manager approved. Final review required.\n\nDetails: @{triggerOutputs()?[‘body/RequestDetails’]}”,

                                                “itemLink”: “@{triggerOutputs()?[‘body/{Link}’]}”

                                            },

                                            “authentication”: “@parameters(‘$authentication’)”

                                        },

                                        “runAfter”: {}

                                    },

                                    “Condition_3_Rejected”: {

                                        “type”: “If”,

                                        “expression”: {

                                            “equals”: [

                                                “@body(‘Approval_3_Director’)?[‘outcome’]”,

                                                “Reject”

                                            ]

                                        },

                                        “actions”: {

                                            “Send_rejection_email_stage3”: {

                                                “type”: “ApiConnection”,

                                                “inputs”: {

                                                    “host”: {

                                                        “connectionName”: “shared_office365”,

                                                        “operationId”: “SendEmailV2”

                                                    },

                                                    “parameters”: {

                                                        “emailMessage”: {

                                                            “to”: “@triggerOutputs()?[‘body/Author/Email’]”,

                                                            “cc”: “admin@company.com”,

                                                            “subject”: “Request #@{triggerOutputs()?[‘body/ID’]} REJECTED by director”,

                                                            “body”: “<p>The request <strong>@{triggerOutputs()?[‘body/Title’]}</strong> has been REJECTED at stage 3 (director).</p><p><strong>Rejected by:</strong> @{body(‘Approval_3_Director’)?[‘responder’][‘displayName’]}</p><p><strong>Comments:</strong> @{body(‘Approval_3_Director’)?[‘comments’]}</p><p><a href=’@{triggerOutputs()?[‘body/{Link}’]}’>Open request</a></p>”,

                                                            “bodyType”: “Html”

                                                        }

                                                    },

                                                    “authentication”: “@parameters(‘$authentication’)”

                                                },

                                                “runAfter”: {}

                                            },

                                            “Update_item_rejected_stage3”: {

                                                “type”: “ApiConnection”,

                                                “inputs”: {

                                                    “host”: {

                                                        “connectionName”: “shared_sharepointonline”,

                                                        “operationId”: “UpdateItem”

                                                    },

                                                    “parameters”: {

                                                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                                                        “table”: “YOUR_MAIN_LIST_NAME”,

                                                        “id”: “@triggerOutputs()?[‘body/ID’]”,

                                                        “item”: {

                                                            “ApprovalStatus”: “Rejected”,

                                                            “RejectionStage”: “Director”,

                                                            “RejectionComments”: “@{body(‘Approval_3_Director’)?[‘comments’]}”

                                                        }

                                                    },

                                                    “authentication”: “@parameters(‘$authentication’)”

                                                },

                                                “runAfter”: {

                                                    “Send_rejection_email_stage3”: [“Succeeded”]

                                                }

                                            },

                                            “Terminate_flow_3”: {

                                                “type”: “Terminate”,

                                                “inputs”: {

                                                    “runStatus”: “Cancelled”,

                                                    “runError”: {

                                                        “code”: “ApprovalRejected”,

                                                        “message”: “Flow terminated because the director rejected the request.”

                                                    }

                                                },

                                                “runAfter”: {

                                                    “Update_item_rejected_stage3”: [“Succeeded”]

                                                }

                                            }

                                        },

                                        “else”: {

                                            “actions”: {

                                                “Update_item_fully_approved”: {

                                                    “type”: “ApiConnection”,

                                                    “inputs”: {

                                                        “host”: {

                                                            “connectionName”: “shared_sharepointonline”,

                                                            “operationId”: “UpdateItem”

                                                        },

                                                        “parameters”: {

                                                            “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                                                            “table”: “YOUR_MAIN_LIST_NAME”,

                                                            “id”: “@triggerOutputs()?[‘body/ID’]”,

                                                            “item”: {

                                                                “ApprovalStatus”: “Fully Approved”,

                                                                “RejectionStage”: null,

                                                                “RejectionComments”: null

                                                            }

                                                        },

                                                        “authentication”: “@parameters(‘$authentication’)”

                                                    },

                                                    “runAfter”: {}

                                                }

                                            },

                                            “runAfter”: {

                                                “Condition_3_Rejected”: [“Succeeded”]

                                            }

                                        },

                                        “runAfter”: {

                                            “Approval_3_Director”: [“Succeeded”]

                                        }

                                    }

                                },

                                “runAfter”: {

                                    “Condition_2_Rejected”: [“Succeeded”]

                                }

                            },

                            “runAfter”: {

                                “Approval_2_Manager”: [“Succeeded”]

                            }

                        }

                    },

                    “runAfter”: {

                        “Condition_1_Rejected”: [“Succeeded”]

                    }

                },

                “runAfter”: {

                    “Approval_1_Selected_Approver”: [“Succeeded”]

                }

            }

        },

        “triggers”: {

            “When_an_item_is_created”: {

                “type”: “ApiConnection”,

                “inputs”: {

                    “host”: {

                        “connectionName”: “shared_sharepointonline”,

                        “operationId”: “OnCreatedItem”

                    },

                    “parameters”: {

                        “dataset”: “https://YOUR_TENANT.sharepoint.com/sites/YOUR_SITE”,

                        “table”: “YOUR_MAIN_LIST_NAME”

                    },

                    “authentication”: “@parameters(‘$authentication’)”

                },

                “splitOn”: “@triggerBody()”

            }

        },

        “contentVersion”: “1.0.0.0”,

        “outputs”: {},

        “parameters”: {

            “$authentication”: {

                “type”: “Object”,

                “defaultValue”: {}

            }

        }

    },

    “kind”: “Stateful”

}

Customization Steps

  1. Replace placeholders:
    • YOUR_TENANT.sharepoint.com/sites/YOUR_SITE
    • YOUR_APPROVERS_LIST_NAME
    • YOUR_MAIN_LIST_NAME
    • manager@company.com and director@company.com
    • admin@company.com (notification recipient)
  2. Column names – ensure they match your SharePoint lists:
    • In main list: ApproverName (lookup to Approvers list), Title, RequestDetails, ApprovalStatus, RejectionStage, RejectionComments
    • In Approvers list: Title, Email
  3. Import the flow – upload the JSON file and map connections for:
    • SharePoint (trigger and all actions)
    • Office 365 Outlook (email actions)
    • Approvals connector
  4. Test – create an item, select an approver, and then have that approver reject with a comment. Verify:
    • The flow terminates immediately (no further approvals sent)
    • Requestor receives rejection email with comments
    • Admin receives a copy
    • SharePoint item shows “Rejected” status and the comments

Additional Tips

  • Comments are always captured – even when an approver approves, you can also record their comments if needed (just access ?[‘comments’]).
  • Admin notification – you can also send to a distribution list or a SharePoint group email.
  • Approval timeout – if you need to add a timeout and auto‑reject, you can configure that in the approval action settings.
  • Terminate action – use Cancelled status so the flow shows as cancelled in run history (not a failure). Use Failed if you want it to appear as an error.

Let me know if you need help adapting the expressions to your exact column internal names or adding an auto‑reminder before timeout.

show the above as configuration steps in Forms, Forms List integrated with Power Automate flows

The user wants a step-by-step configuration guide focused on Microsoft Forms and SharePoint Lists, integrated with Power Automate for a three-stage sequential approval workflow with rejection handling. I need to search for relevant configuration steps and best practices.

Found 56 web pages

The search results include some potentially useful links. I will open them to gather detailed information.

Read 5 pages

Approval Workflow Using Microsoft Forms in Power Automate

シーケンシャル承認を設定する – Power Automate

Three-Stage Document Approval Process in SharePoint with Flows – @WonderLaura – Laura Rogers

Using Forms and Approvals – Microsoft Q&A

SharePoint Approval Requests in Power Automate | ESPC Conference, 2026

The search results provide useful information. The spguides article details how to create an approval workflow using Microsoft Forms and Power Automate, including saving form responses to a SharePoint list. The learn.microsoft.com page explains sequential approvals. The wonderlaura.com article covers a three-stage document approval process. The sharepointeurope.com article discusses SharePoint approval requests in Power Automate. My answer will be a step-by-step configuration guide covering Microsoft Forms, SharePoint list setup, Power Automate flow creation, and the sequential approval logic with rejection handling. I will structure the answer with clear sections and use a tabbed interface for the different stages.

This is an excellent, practical implementation that follows the best practice of separating the data storage and the user interface. It makes your approval workflow robust and auditable.

Here is the step-by-step configuration guide to build this three-stage sequential approval system using Microsoft Forms, SharePoint, and Power Automate.

Phase 1: Building the Foundation (Approvers List & SharePoint Form Responses List)

This phase sets up the data storage that will power your entire workflow.

Step 1: Create the ‘Approvers’ Lookup List in SharePoint
This list holds the dropdown options for the requestor.

  1. Navigate to your SharePoint site → New → List.
  2. Name it Approvers (e.g., “Manager Approvers”).
  3. Add the following two columns:
    • Title (Default): This will be the visible name in the dropdown (e.g., “John Smith”). Rename it to ApproverName.
    • ApproverEmail: Add a new column of type Single line of text to store the approver’s email address (e.g., john.smith@company.com).

Step 2: Create the Main ‘Form Responses’ List in SharePoint
This list stores every form submission.

  1. Create a second list and name it Form Responses.
  2. Add the key columns you will need:
    • RequestTitle (Single line of text): A short description of the request.
    • RequestDetails (Multiple lines of text): All details from the form.
    • RequestorEmail (Single line of text): The submitter’s email address.
    • SelectedApprover (Lookup): This is the most critical column. Add a new Lookup column, name it SelectedApprover, and point it to the ApproverName column in your ‘Approvers’ list.
    • ApprovalStatus (Choice): Add a Choice column to track progress (values: Pending, Stage1_Approved, Stage2_Approved, Fully Approved, Rejected).
    • RejectionComments (Multiple lines of text): To capture why a request was denied.
    • RejectionStage (Single line of text): To log at which stage the rejection occurred.
  3. Populate the Approvers list with real users and their emails so the dropdown in the next phase has values.

Phase 2: Creating the Request Form (Microsoft Forms)

This is the user-friendly interface for the requestor.

Step 1: Create a New Microsoft Form

  1. Go to Microsoft Forms and create a new form.
  2. Add all necessary questions for your request (e.g., “Request Title”, “Request Details”).

Step 2: Add the ‘Approver Dropdown’ Question
This is the manual step that connects the form to your SharePoint data.

  1. Add a new question of type Choice.
  2. Click the “…” (More options) menu and select “Insert a drop-down list”.
  3. Here, you must manually enter the names from your Approvers list into the dropdown options. While Forms doesn’t support dynamic lookups to SharePoint, this manual step is a common and accepted method. For a fully automated solution, you would need to build a Power App.

Phase 3: Building the Power Automate Flow (The 3-Stage Engine)

This is the core logic that connects all the components.

Step 1: Create the Flow and Set Up the Trigger

  1. In Power Automate, create an Automated cloud flow.
  2. Name: 3-Stage Sequential Approval Flow
  3. Trigger: Search for and select “When a new response is submitted” (Microsoft Forms). Choose your form from the dropdown.

Step 2: Get Form Data and Create the SharePoint Item

  1. Action: Add “Get response details” (Microsoft Forms). Use the dynamic Response ID from the trigger.
  2. Action: Add “Create item” (SharePoint). Map the Form fields (e.g., RequestTitle) to the corresponding columns in your Form Responses list.

Step 3: Get the Email of the Requestor-Selected Approver

  1. Action: Add “Get items” (SharePoint).
  2. Site Address: Your SharePoint site.
  3. List Name: Your Approvers list.
  4. Filter Query: This uses the value from the form to find the correct row in the Approvers list.

text

ApproverName eq ‘@{triggerOutputs()?[‘body/r2d3f…’]}’

    • *Crucially, replace r2d3f… with the actual ID of your “Approver Name” question from the form. You can find this ID in the URL when editing the form.

Step 4: Implement the 3-Stage Sequential Logic

  • For the first stage, add a “Start and wait for an approval” action. Set the Assigned To field to the ApproverEmail retrieved from the Get items action.
  • For the second and third stages, add additional “Start and wait for an approval” actions. Set their Assigned To fields to the specific, hardcoded email addresses you defined (e.g., manager@company.com).

Step 5: Add Conditions and Rejection Handling for Each Stage
After each of the three approval actions, insert a Condition to check the outcome.

  1. In the Condition action, set the left field to the Outcome dynamic content from the approval.
  2. Set the condition to is equal to Reject.
  3. In the “If yes” branch, add the actions to handle a rejection:
    • Send an email (V2): Notify the requestor and admin. Use dynamic content to include the approval Comments in the email body.
    • Update item: Update the Form Responses list item to set ApprovalStatus to Rejected and log the RejectionComments and RejectionStage.
    • Terminate: Add a Terminate action to stop the flow and prevent any further approvals from being sent.
  4. In the “If no” branch, the flow should continue to the next stage’s approval action.

Phase 4: How It All Works Together

Here’s a final view of how the pieces connect to form the complete workflow:

  • Requestor Fills Out Form: The employee visits your Microsoft Form and submits a request. Crucially, they use the dropdown menu to select their preferred first approver.
  • Form Submission Triggers Flow: Microsoft Forms notifies Power Automate that a new response has arrived.
  • Power Automate Runs the Multi-Stage Logic:
    • Stage 1: Power Automate uses the selected name to look up the email address from your hidden ‘Approvers’ SharePoint list. It then sends the approval request to that specific person.
    • Outcome Check: If the first approver rejects with a comment, the flow immediately sends a detailed email to the requestor and admin, updates the ‘Form Responses’ list, and terminates.
    • Stage 2 & Stage 3: If the request is approved, the flow proceeds to the next stage, sending requests to the hardcoded second and third approvers in sequence, checking for rejection at each step.
  • Final Outcome: If all three stages approve, the flow updates the ‘Form Responses’ list status to Fully Approved, completing the process.

Step 5: Testing Your Completed Workflow

  • Submit a Request: Fill out your Microsoft Form and select an approver from the dropdown.
  • Check the SharePoint List: Verify a new item was created in your Form Responses list.
  • Approve a Stage: The selected approver should receive an email. Have them click “Approve”.
  • Test Rejection Handling: Have the selected approver reject the request and provide a comment. Verify that:
    • The requestor and admin receive a detailed rejection email.
    • The flow terminates immediately without sending further approvals.
    • The Form Responses list item is updated with Rejected status and the rejection comment.
  • Test Full Approval: Run a test where all three stages are approved. Check that the final status in SharePoint updates to Fully Approved.

 

Can phase 2 use sharepoint form list instead of Microsoft form?

We need to adjust the answer: Phase 2 should use a SharePoint list form (the native SharePoint list forms) instead of Microsoft Forms. The user wants to know if Phase 2 can use SharePoint form list instead of Microsoft Form. So we need to provide configuration steps for using SharePoint list forms (the default New/Edit/Display forms of a SharePoint list) as the requestor interface, with a dropdown (lookup column) for approver selection. Then integrate with Power Automate as before. Provide clear steps for setting up the SharePoint list form (customizing the form if needed using Power Apps or just using default list form). Also adjust the flow trigger from “When a new response is submitted” (Forms) to “When an item is created” (SharePoint). Provide a concise but complete answer.

Yes, absolutely. Phase 2 can (and often should) use a SharePoint list form instead of Microsoft Forms. This approach keeps everything within SharePoint, gives you native lookup columns (dynamic dropdowns), and simplifies the Power Automate trigger.

Below is the adjusted configuration where Phase 2 uses a SharePoint list form (the default New item form of a SharePoint list) as the requestor interface.

Phase 2 (Adjusted): Using a SharePoint List Form as the Requestor Interface

Step 1: Create a SharePoint List (the “Request List”) – This replaces the separate Form Responses list

Instead of having a separate “Form Responses” list, you will create a single SharePoint list that:

  • Stores all request data (like a database table)
  • Provides the New item form where requestors submit requests
  • Contains the Approver dropdown (via a Lookup column to the Approvers list)

How to create it:

  1. Go to your SharePoint site → New → List.
  2. Name it Requests (or Expense Requests etc.).
  3. Add columns as needed:
    • RequestTitle (Single line of text)
    • RequestDetails (Multiple lines of text)
    • RequestorEmail (Single line of text) – you can auto‑fill this using a Person or Group column or let the user type it.
    • SelectedApprover – add a Lookup column:
      • Name: SelectedApprover
      • Get information from: Choose the Approvers list (created in Phase 1)
      • In this column: Choose ApproverName (the column storing display names)
      • This automatically creates a dropdown in the New item form that pulls all approver names from the Approvers list.
    • ApprovalStatus (Choice) – values: Pending, Stage1_Approved, Stage2_Approved, Fully Approved, Rejected
    • RejectionComments (Multiple lines of text)
    • RejectionStage (Single line of text)

Step 2: Customise the SharePoint List Form (Optional but recommended)

By default, the SharePoint list New item form is functional but plain. You can:

  • Use the default form – fine for basic scenarios. Requestors click + New on the list to open the form.
  • Customise with Power Apps (built‑in) – for better layout, validation, or conditional fields. Click Integrate → Power Apps → Customise forms.

The dropdown for SelectedApprover will automatically appear as a drop‑down list populated from the Approvers list – no manual entry needed.

Step 3: Share the Form Link with Requestors

You can give requestors a direct link to the New item form:

  • Open your Requests list in SharePoint.
  • Click + New to open the form.
  • Copy the URL from your browser’s address bar. It will look like:

text

https://yourtenant.sharepoint.com/sites/yoursite/Lists/Requests/NewForm.aspx

  • Distribute this link via email, Teams, or a company intranet page.

Adjustments to Power Automate Flow (Phase 3)

Because you are now using a SharePoint list instead of Microsoft Forms, the flow trigger changes from “When a new response is submitted” to “When an item is created” (SharePoint). The rest of the logic remains nearly identical.

Updated Flow Trigger

  1. Create an Automated cloud flow.
  2. Trigger: When an item is created (SharePoint).
    • Site Address: Your SharePoint site.
    • List Name: Requests (your main request list).

Updated “Get items” to Find Approver Email

The SelectedApprover column in the Requests list is a Lookup column. In Power Automate, it returns an object like:

json

{

  “@odata.type”: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference”,

  “Id”: 3,

  “Value”: “John Smith”

}

To build the Filter Query for the Approvers list, you need to use the Value property.

Filter Query expression:

powerapps

ApproverName eq ‘@{triggerOutputs()?[‘body/SelectedApprover/Value’]}’

Rest of the Flow – No Change

All other steps remain identical:

  • Compose to extract email from the Get items result.
  • Three sequential approvals (first = selected approver, second = fixed manager, third = fixed director).
  • Conditions to handle rejection at each stage, send emails, update status, and terminate.

Example: Updated “Get items” Action Configuration

Field

Value

Site Address

https://yourtenant.sharepoint.com/sites/yoursite

List Name

Approvers

Filter Query

ApproverName eq ‘@{triggerOutputs()?[‘body/SelectedApprover/Value’]}’

Note: ApproverName is the column name in the Approvers list. SelectedApprover is the lookup column name in the Requests list.

Advantages of Using SharePoint List Forms

Aspect

Benefit

Dynamic dropdown

The lookup column automatically stays in sync with the Approvers list – no manual updating.

No extra list

You don’t need a separate “Form Responses” list; the main list is both the form backend and the data store.

Simpler Power Automate

Trigger is When an item is created – no need to call “Get response details” or parse form IDs.

Built‑in versioning & permissions

Inherits SharePoint security – you can control who can submit vs. approve.

Customisable forms

Use Power Apps to enhance the form without writing code.

Testing the SharePoint List Form Workflow

  1. Add an approver to the Approvers list (e.g., Anna White with email anna@company.com).
  2. Open the SharePoint list Requests → click + New.
  3. Fill out the form – the SelectedApprover dropdown will show Anna White.
  4. Submit – the item is created.
  5. Power Automate triggers:
    • Looks up anna@company.com from the Approvers list.
    • Sends approval request to Anna.
    • After Anna approves, sends to manager, then director.
    • If any rejects with a comment, the flow terminates and sends notifications.

Summary of Phases (Updated)

Phase

Tool

Purpose

Phase 1

SharePoint List (Approvers)

Stores approver names + emails for the dropdown.

Phase 2

SharePoint List (Requests) with Lookup column to Approvers

Provides the requestor form (dropdown auto‑populated) and stores all submissions.

Phase 3

Power Automate

Triggered on item creation; executes 3‑stage sequential approval with rejection handling.

Phase 4

Email (Outlook) & SharePoint updates

Notify requestor/admin, update status, terminate on rejection.

This end‑to‑end SharePoint‑native solution is often simpler to maintain than mixing Microsoft Forms, and it gives you a fully dynamic dropdown without manual re‑entry.

Would you like me to provide the exact JSON flow template adjusted for the SharePoint trigger and lookup column filter query?

Will the approval flows be captured in Teams?

The user wants to know if the approval flows we designed will be captured in Teams. I need to provide a comprehensive answer explaining how approvals appear in Teams, including adaptive cards, the approval app, notifications, and how to ensure they are captured. I should also address potential issues and best practices. To gather this information, I will search for relevant documentation and articles.

Found 53 web pages

The search results provide information on how Power Automate approvals integrate with Teams. The default “Start and wait for an approval” action sends an email notification and also a Teams notification (if the user has Teams). The approval request appears in the Teams Approvals app. Adaptive cards can be used for custom approvals in Teams channels. There are also troubleshooting tips. I will structure the answer to explain the default integration, the Teams Approvals app, Adaptive Cards for custom approvals, and best practices.

Yes, the approvals will be integrated into Microsoft Teams. Here’s how the workflow you’ve designed will be captured:

How Approvals Appear in Teams

By default, the “Start and wait for an approval” action in Power Automate sends notifications through both email and Microsoft Teams. When an approver receives a request, they get:

  1. A Teams notification – a pop-up alert in their Teams activity feed
  2. An entry in the Teams Approvals app – accessible from the left sidebar in Teams
  3. An email notification – sent to their Outlook inbox

Approvers can respond directly from any of these channels – email, Teams notification, or the Teams Approvals app – and the response is captured by Power Automate.

What the Approver Sees in Teams

When an approver receives a request:

Channel

Experience

Teams Activity Feed

A notification card appears with Approve/Reject buttons. Clicking either button opens a dialog where they can add comments.

Teams Approvals App

All pending and completed approvals are listed in one place. They can filter by status and review history.

Teams Chat/Channel

Not automatically sent here unless you specifically add the “Post an adaptive card to a Teams channel” action (see below).

The Default vs. Adaptive Card Experience

Feature

Default Approval Action

Adaptive Card in Teams Channel

Where it appears

Approvals app + email + activity feed

Specified Teams channel (shared)

Visibility

Personal (only the assigned approver)

Team-visible (all channel members can see the card)

Collaboration

Single approver responds

Multiple people can see responses

Setup complexity

Simple – just add the action

Requires JSON card design

Using Adaptive Cards for Team-Visible Approvals

If you want the approval request to appear in a Teams channel (where multiple team members can see it, comment, and collaborate), you can replace the standard approval action with the “Post an adaptive card to a Teams channel and wait for a response” action.

This approach:

  • Posts an interactive card directly to a specific Teams channel
  • Allows team members to see who approved/rejected and when
  • Is ideal for scenarios where approval decisions should be transparent to the whole team

To implement this for your 3‑stage flow, you would:

  1. Remove the standard “Start and wait for an approval” actions
  2. Add “Post an adaptive card to a Teams channel and wait for a response” for each stage
  3. Design the Adaptive Card JSON (you can use the Adaptive Cards Designer to build it visually)

Important Limitations to Know

Responses via Email or Action Center Don’t Update the Adaptive Card

If an approver responds through email or the Power Automate action center, the Adaptive Card in Teams will not auto-update its status. This can lead to mismatches where the card shows pending while the flow has already recorded the response.

Attachments Don’t Display in the Teams Approvals App

Attachments included in an approval request do not appear when viewing the approval in the Teams Approvals app – this is a known issue Microsoft is actively working to fix.

The Adaptive Card Doesn’t Auto-Refresh

Unlike the standard approval action (which updates across all Microsoft 365 surfaces), an Adaptive Card posted to a Teams channel is static after posting. If you need real‑time status updates visible to all team members, consider using the Approvals app or implementing a refresh mechanism.

Best Practice Recommendation for Your 3‑Stage Flow

For your scenario (requestor‑selected first approver + two fixed approvers), here’s what I recommend:

Approach

When to Use

Standard “Start and wait for an approval”

Default choice – works seamlessly with Teams Approvals app, email, and activity feed. Approvers can respond from anywhere.

Adaptive Card in Teams channel

Use only if you need the approval request to be visible to an entire team for transparency or collaborative decision‑making. Requires additional setup and has limitations.

For most business approval scenarios, the standard approval action provides the best user experience because it:

  • Works consistently across email, Teams, and mobile devices
  • Automatically syncs status across all surfaces
  • Requires no custom JSON design
  • Is fully supported by Microsoft

Verifying Teams Integration in Your Flow

To ensure your flow sends Teams notifications:

  1. Open your flow in Power Automate
  2. Select the “Start and wait for an approval” action
  3. In the action settings, confirm “Notification Type” includes Teams (this is enabled by default)

If approvals are not appearing in Teams, try:

  • Signing out of Teams and signing back in
  • Checking the approval status in the Power Automate web portal (make.powerautomate.com > Approvals) – if it appears there, the issue is with Teams sync, not the flow

Summary

Question

Answer

Will approvers receive Teams notifications?

✅ Yes – automatically with the standard approval action

Will approvals appear in the Teams Approvals app?

✅ Yes – all approvals sent to a user appear here

Can I post approvals to a Teams channel?

✅ Yes – using Adaptive Cards, but with limitations

Should I switch to Adaptive Cards for this flow?

❌ Not necessary – the standard approval action provides better sync and reliability

Would you like me to provide a step‑by‑step guide for implementing the Adaptive Card approach, or help you troubleshoot if your approvals aren’t appearing in Teams?

Yes. provide a step by step guide for implementing the Adaptive Card approach, and show how to troubleshoot if approvals aren’t appearing in Teams

The user wants a step-by-step guide for implementing the Adaptive Card approach for their three-stage sequential approval flow, as well as troubleshooting if approvals aren’t appearing in Teams. I need to provide detailed instructions on how to use the “Post an adaptive card to a Teams channel and wait for a response” action in Power Automate, including designing the Adaptive Card JSON, setting up the flow with three stages, handling rejections, and troubleshooting Teams approval issues. I should search for relevant documentation and guides.

Found 36 web pages

The search results include some potentially useful links. Result 0 might be a raw markdown guide. Result 1 is a Microsoft Learn training module. Result 2 is a LinkedIn article. Result 5 might be a raw guide. I should open these to gather detailed information.

Read 7 pages

https://raw.githubusercontent.com/MicrosoftDocs/power-automate-docs/main/articles/create-adaptive-cards.md

Exercise – Use Microsoft Teams to get approvals – Training

https://raw.githubusercontent.com/MicrosoftDocs/power-automate-docs/0ed479b2a82bcd5103eafffac83218ffe874d4be/articles/create-adaptive-cards.md

Build Adaptive cards for existing Approval tasks

Power Automate-Genehmigungen werden in Microsoft Teams angezeigt – Microsoft Q&A

View All

The search results provide some relevant information. The Microsoft Learn article (result 4) provides a basic guide for posting adaptive cards. The known issues (results 9 and 10) mention adaptive card mismatches. The troubleshooting guide (result 8) offers steps for approvals not showing in Teams. I should also search for a sample JSON template.

Found 9 web pages

Result 2 might be useful. Let’s open it.

Read 1 page

Create Approvals via Adaptive Cards Using Power Automate

I’ll structure the response in two main parts: the implementation guide (with prerequisite checks, building the approval request flow, designing the adaptive card, setting up the three-stage flow, and handling responses) and a troubleshooting section. I’ll cite relevant sources.

Here is a step-by-step guide to implementing the Adaptive Card approval process and a dedicated troubleshooting section.

Part 1: Step-by-Step Implementation Guide

🚦 Prerequisites

  • Microsoft Teams: The target channel where the Adaptive Card will be posted must exist.
  • Workflows App: The “Workflows” app must be installed in Microsoft Teams for Power Automate to post messages. It’s usually pre-installed, but you should verify it in your Teams admin center.

🔄 Building the Approval Request Flow

Step 1: Create and Configure the “Post an Adaptive Card” Action

This is the core action that will send the interactive card to the channel.

  1. In your Power Automate flow, add a new action.
  2. Search for and select the Post an adaptive card to a Teams channel and wait for a response action.
  3. Connection: Select or create a connection for Microsoft Teams.
  4. Team: Choose the Microsoft Team that contains the target channel.
  5. Channel: Select the specific channel where you want the card to appear.

Step 2: Design the Adaptive Card JSON

The action’s Message box requires a JSON payload that defines the card’s appearance and behavior. Use this template for a standard “Approve/Reject” request:

json

{

    “$schema”: “http://adaptivecards.io/schemas/adaptive-card.json”,

    “type”: “AdaptiveCard”,

    “version”: “1.2”,

    “body”: [

        {

            “type”: “TextBlock”,

            “text”: “New Approval Request: {Dynamic_Request_Title}”,

            “weight”: “Bolder”,

            “size”: “Medium”

        },

        {

            “type”: “FactSet”,

            “facts”: [

                {

                    “title”: “Request Details:”,

                    “value”: “{Dynamic_Request_Details}”

                },

                {

                    “title”: “Requestor:”,

                    “value”: “{Dynamic_Requestor_Name}”

                }

            ]

        },

        {

            “type”: “Input.Text”,

            “id”: “Comments”,

            “placeholder”: “Add your comments here…”,

            “isMultiline”: true

        }

    ],

    “actions”: [

        {

            “type”: “Action.Submit”,

            “title”: “Approve”,

            “data”: {

                “action”: “Approve”

            }

        },

        {

            “type”: “Action.Submit”,

            “title”: “Reject”,

            “data”: {

                “action”: “Reject”

            }

        }

    ]

}

Customization Tips:

  • Replace {Dynamic_Request_Title}, {Dynamic_Request_Details}, and {Dynamic_Requestor_Name} with dynamic content from your trigger.
  • The “id”: “Comments” field creates a text box for approvers to leave notes.
  • The “actions” array creates the Approve and Reject buttons. When clicked, the data (including action and any Comments) is sent back to the flow.

🧩 Setting Up the 3-Stage Sequential Flow

Here is how to sequence your stages.

Stage 1: First Approver (Requestor-Selected)

  • Use the Post an adaptive card to a Teams channel and wait for a response action as described above.
  • The card will be posted to the designated Teams channel.
  • The flow will pause and wait for the first approver to click a button.

Stage 2: Second Approver (Fixed Email)

  • Add a second Post an adaptive card to a Teams channel and wait for a response action.
  • This card will be posted in the same Teams channel.
  • Crucially, the flow will only proceed to this stage after the first approver has approved the request.

Stage 3: Third Approver (Fixed Email)

  • Repeat the process for the third and final approver.

✅ Handling the Response

After the Post an adaptive card… action, the flow will have access to the data submitted by the approver.

  1. Add a “Condition” Control: Add a Condition action after the Adaptive Card action.
  2. Configure the Condition: Set it to check the value from the card’s response:
    • Left field: Click in the field and select body(‘Post_an_adaptive_card…’)?[‘data’]?[‘action’] from the dynamic content list.
    • Operator: is equal to
    • Right field: Type Approve.
  3. Map the “If yes” Branch: In this branch, add the actions for a successful approval (e.g., update SharePoint status, proceed to the next stage).
  4. Map the “If no” Branch: In this branch, add the actions for a rejection:
    • Capture Comments: Use body(‘Post_an_adaptive_card…’)?[‘data’]?[‘Comments’].
    • Send Rejection Emails: Use the Send an email (V2) action to notify the requestor and admin. Include the captured comments in the email body.
    • Terminate: Use a Terminate action to stop the flow immediately after a rejection.
  5. Repeat: Add this conditional logic after each of the three Adaptive Card actions.

Part 2: Troubleshooting When Approvals Aren’t Appearing in Teams

🔍 Check 1: The “Card vs. Email/Action Center” Mismatch

  • The Problem: If an approver responds to the approval via an email notification or through the Power Automate action center (instead of the Teams card), the card in the Teams channel will not auto-update its status. This can cause confusion, as the card may still show “Pending” even after the approval has been processed.
  • The Fix: The best way to prevent this is to disable the default email notification that is sent when an approval is created. This ensures that the only way to respond is through the card in Teams, keeping the status in sync.
    1. In your Power Automate flow, click on the Post an adaptive card to a Teams channel and wait for a response action.
    2. Click Show advanced options.
    3. Look for a setting like Disable default email notification and toggle it to Yes.
  • If the issue has already occurred: A user can still respond by finding the approval request in the Power Automate web portal (make.powerautomate.com > Approvals). The admin can also manually delete any abandoned approvals from the action center.

🔑 Check 2: User Permissions and Licenses

  • The Problem: Guest users or users without the correct permissions will not see the approval.
  • The Fix:
    • Guest Users: A guest user must be assigned a valid Power Automate license (per-user or Microsoft 365-based) to view or act on an approval. This is not enabled by default.
    • Internal Users: Ensure the user has at least the Basic User and Approval User roles in the Power Platform environment where the flow runs. They also need read permissions for the underlying data tables (e.g., SharePoint list items).

🔄 Check 3: Teams Client Cache and Sync Issues

  • The Problem: The Teams desktop client can sometimes cache outdated information, leading to errors like “Something went wrong”.
  • The Fix:
    1. Sign Out and Back In: Sign out of Microsoft Teams completely, close the application, then open it and sign in again.
    2. Check the Power Automate Portal: If the approval appears correctly in the Power Automate web portal (make.powerautomate.com > Approvals) but not in Teams, the issue is almost certainly a client-side cache problem.

🛠️ Check 4: Teams Policy Settings

  • The Problem: Microsoft Teams admin policies might be preventing the “Workflows” app or other necessary apps from running.
  • The Fix:
    1. Open the Microsoft Teams admin center.
    2. Navigate to Teams apps > Permission policies.
    3. Select the policy assigned to the affected user and ensure that the Workflows app and the Approvals app are allowed.

Adaptive Card vs. Standard Approval: A Quick Comparison

To help you decide, here is a summary of the key differences:

Feature

Standard Approval Action

Adaptive Card Approach

Visibility

Personal (only the assigned approver)

Team-visible (entire channel sees the card)

Response Methods

Email, Teams Approvals app, Power Automate portal

Only from the card in Teams (to avoid mismatch)

Collaboration

Single approver responds

Multiple team members can see responses

Setup Complexity

Simple – just add the action

Complex – requires manual JSON design

Best For

Most business approval scenarios

Transparent, team-based decisions

For most business approval scenarios, the Standard Approval Action is the simpler, more reliable choice. However, if you need a transparent, team-visible approval process, the Adaptive Card method is the way to go.

Do you have a specific error message you’d like me to help you troubleshoot?