Let's POWER Automate

From no-code to low-code

Menu
  • Expressions
  • Filters
  • General
  • Application specific solutions
    • Dataverse
    • Excel
    • Forms
    • Outlook
    • Planner
    • Power Apps
    • SharePoint
    • Teams
  • Triggers
  • Ready to use solutions
    • Approval Process Solution
    • Task Delegation App
    • The Ultimate Power Automate expressions cheat sheet
    • Power Automate HTTP requests to SharePoint cheat sheet
    • Power Automate HTTP requests to Graph API cheat sheet
  • ABOUT ME
  • Get help with your flow
  • POWER PLATFORM SERVICES
Menu

Build Adaptive cards for existing Approval tasks

Posted on July 19, 2025July 19, 2025 by Tom

“Can I build Adaptive cards for existing Approval tasks to send reminders to approvers? Including the approval buttons?”


Approval task reminders are a topic I already published a few articles about – how to build a basic reminder, send them via email, or trigger a Teams follow up. This time it’ll be another approach, more specifically Adaptive cards.

How do you build an adaptive card for an existing approval task? A card with the clickable buttons that’ll complete the task upon a click?

Don’t store the adaptive cards

The easiest way could be to store the adaptive card after you create the task. But this approach is not ideal – it must be implemented in each of the flows, you’ll have to store the adaptive card somewhere, and it’s valid only for the original approver. If you reassign the task to somebody else, the adaptive card turns useless.

Nevertheless, you can take the adaptive card to see what it looks like.

Build the adaptive cards instead

That’s why I believe it’s better to build the card when needed. You can search for all tasks directly in Dataverse and if there’re any opened for too long, you can prepare the adaptive card.

What do you need to build it? Again, a combination of rows from the Approval and Approval Request table.

From the Approval table the general information about the task like the Title, Item link, or the requestor.

From the Approval Request table the specific request details – owner of the task, response options, etc.

Additionally, as each of the buttons represents one of the available responses, you’ll need a variable to keep track of their number.

Prepare the buttons

The JSON structure is as below, everything between ## are placeholders to replace:

{
  "type": "Action.ShowCard",
  "card": {
    "type": "AdaptiveCard",
    "version": "1.0",
    "body": [
      {
        "type": "TextBlock",
        "text": "Comments",
        "wrap": true
      },
      {
        "type": "Input.Text",
        "id": "comments##NUMBER##",
        "placeholder": "Enter comments",
        "isMultiline": true,
        "maxLength": 2048
      }
    ],
    "actions": [
      {
        "type": "Action.Submit",
        "data": {
          "Environment": "##ENVIRONMENTID##",
          "ApprovalTitle": "##TASKTITLE##",
          "ApprovalLink": "https://make.powerautomate.com/environments/##ENVIRONMENTID##/approvals/received/##APPROVALID##",
          "ApprovalName": "##APPROVALID##",
          "OnBehalfOfNotice": "Requested for ##APPROVALOWNERNAME## <##APPROVALOWNEREMAIL##>",
          "CreatorName": "##TASKOWNERNAME##",
          "CreatorEmail": "##TASKOWNEREMAIL##",
          "CreationTime": "\"##CREATIONDATE##\"",
          "MessageTitle": "##TASKTITLE##",
          "Details": "##APPROVALDETAILS##",
          "Options": [##RESPONSEOPTIONS##],
          "SelectedOption": "##CURRENTITEM##",
          "ActionType": 1
        },
        "title": "Submit"
      }
    ]
  },
  "title": "##CURRENTITEM##"
}

Since you need an array where each button is a separate object, add an ‘Apply to each’ and loop through all the response options. To turn the string with options into an array use the JSON(…) expression.

Input: 
json(outputs('Get_a_row_by_ID_-_approval_request')?['body/msdyn_flow_approvalrequest_options'])

Follow with a ‘Compose’ action and replace the placeholders in the buttons JSON. Some can be replaced by expressions, like the environment id, others come from the Dataverse rows. The CreationTime format it expects is:

formatDateTime(outputs('Get_a_row_by_ID_-_approval_request')?['body/createdon'], 'dddd, dd MMMM yyyy HH:mm')

Increment the index variable by 1 with each loop.

Build Adaptive cards for existing Approval tasks

Add them to the adaptive card

Take the output array and use it as the ActionSet in the adaptive card. The code below will create an adaptive card that’ll contain only the buttons.

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "ActionSet",
      "actions": ##BUTTONSJSON##
    }
  ]
}
Build Adaptive cards for existing Approval tasks

Feel free to add also the content before the buttons that’s available in the ‘Create an approval’ action output. Just don’t forget to replace the placeholders – task title, date, link, etc.

All that’s left is to send the adaptive card.

Build Adaptive cards for existing Approval tasks

Summary

As you can see, it’s not that complicated to build adaptive cards for existing Approval tasks, to let users approve directly from Teams. The adaptive cards have a given structure, a piece of JSON code that you can replicate and adjust to your specific needs. Load all the necessary data from the Approval and Approval Request tables, prepare JSON objects for each button, add the texts around it, and send it as a Teams message.


πŸš€ Master Power Automate

Join 2,100+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

1 thought on “Build Adaptive cards for existing Approval tasks”

  1. Al says:
    July 23, 2025 at 10:41 pm

    I’m doing tests on this right now – but trying to do it from the existing card that the “create approval” action generates.

    Regardless, I’m also stuck doing the next step, which is also sending an email with the same approval. I tried to send an approval to my email, inspect on the network tab and saw that it uses the action Action.Http, and uses the following URL to POST:
    “https://emea.api.flow.microsoft.com/callbacks/actionableEmail/environments//approvals//approvalResponses?api-version=1”

    However, it also sends additional info, including clientTelemetry, adaptiveCardSignature and adaptiveCardHash, connectorSenderGuid, etc., that are outside the Action.Http and are probably validated in a table somewhere. Using a different user, I got a 401 error (fair, that user didn’t have any rights to approve/deny the request), and using my own user I had a “the action cannot be completed” in outlook.

    So I’m kinda stuck. Really wanted to have more control over the card (comments field only on some options, send the email as an internal user, etc) but I don’t think it’s possible right now.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

πŸš€ Master Power Automate

Join 2,100+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

Still exchanging emails to get things approved?

Get the Approval Process solution to skip the hard part and deploy an automated, fully functional approval solution on a SharePoint list in minutes! And then the next one, and the next one...

Approval Template Preview ✨ Learn more ✨

Are your approvals stuck due to unavailable approvers?

Keep your approvals running with the Approval task delegation app! Reassign any existing approval task to another user with a single click - no more waiting for absent approvers!

Power Automate approval task delegation ✨ Learn more ✨

Turn ideas into flows with ease!

Grab the complete Power Automate Cheat Sheet Bundleβ€”everything you need to master expressions, SharePoint HTTP calls, and Graph API in Power Automate.

Cheat Sheet Bundle Preview ✨ Get the Cheat Sheets

Didn't find what you were looking for?
Need to adjust a solution to fit your needs?
Or would you just like to get an assistance from somebody with thousands of hours of experience with Power Automate?

Power Automate blogs worth visiting

Damien Bird
Dennis (Expiscornovus)
Paul Murana

©2025 Let's POWER Automate | Theme by SuperbThemes