Back to blog
Show a SharePoint List Inside Outlook with an Adaptive Card
Power Automate Show a SharePoint List Inside Outlook with an Ad...

Show a SharePoint List Inside Outlook with an Adaptive Card

M

Mick verified

  • 8 min read
  • 12

Comments: 0

Most automated emails send a link and hope someone clicks it. Actionable messages let you put the information, and later the buttons, directly inside the email. In this post I build a simple example from start to finish: a SharePoint list of team members shown as a table-style card inside Outlook, sent in a single email. Then I cover the step most tutorials skip: registering a provider so you get the originator ID that makes the card appear.

This is part one of a series. This post is display only. The next post adds a comments box and a Submit button that calls a Power Automate flow using an HTTP action.

What you will build

An email that shows every item in a SharePoint list (name, age and work type) as rows in an adaptive card. One email, all items, no links to click.

How it works

There are three pieces:

1. The card. JSON that describes the layout. It is embedded in the email's HTML inside a <script type="application/adaptivecard+json"> tag.

2. The originator ID. A GUID for a provider you register with Microsoft. Outlook uses it to decide whether the sender is allowed to send cards.

3. The email. Sent from Power Automate with the card JSON in the HTML body. Any normal text in the body is a fallback for clients that can't show the card.

If the originator ID is missing, wrong, or not approved for the recipient, the email still arrives but shows only the fallback text. That is the number one reason people think their card is broken.

What you need

• A Microsoft 365 mailbox on Exchange Online for the sender, and Exchange Online mailboxes for the recipients

• A SharePoint list and Power Automate

• Access to the Actionable Email Developer Dashboard

• An Exchange administrator, if you want to send to people other than yourself and a few test users

Step 1: Create the SharePoint list

Create a list called Sample Adaptive Card with these columns:

Column

Type

Name (the default Title column)

Single line of text

Age

Number

Work Type

Choice: On Site, Remote, Hybrid

Add a handful of rows. Check each column's internal name in the list settings, because the flow uses internal names. In this post I assume Title, Age and WorkType.

Step 2: Get your originator ID

Do this before building the flow, because the card needs the ID.

1. Sign in to the Actionable Email Developer Dashboard at https://outlook.office.com/connectors/oam/publish.

2. Choose to create a new provider.

3. Fill in the registration form. The labels can vary slightly, but you will provide:

o A name for the provider, such as "Team List Demo".

o The sender email address. This must be exactly the address the email will be sent from. If the flow uses your own mailbox connection, use your address. Messages from any other sender are not processed.

o Target URLs. These are the HTTPS URLs your card's buttons will call. This post has no buttons, but you will add one in part two, so plan for the URL of that flow. You can edit the provider later, and changes may need approval again.

o The scope (see below).

4. If asked whether this is a Power Automate scenario, choose Yes when your buttons will call a Power Automate HTTP trigger. Microsoft's documentation says this sets the token type to the Entra-based option automatically, and the target URL field can use a regular expression.

5. Submit the registration. The dashboard then shows your provider with a Provider ID, a GUID. That GUID is your originator ID. Copy it.

Choosing a scope

Scope

Who can receive the card

Approval

Test users ("Sent to me")

Only the addresses you list, in your own organization

Automatic

Organization

Anyone in your Microsoft 365 organization

An Exchange administrator in your tenant must approve it

Global

Any Microsoft 365 user

Reviewed by Microsoft

Start with test users while you build. When you are ready to send to others, create or change the provider to Organization scope. Exchange administrators approve these in the Actionable Messages admin dashboard at https://outlook.office.com/connectors/oam/admin. Until the status shows approved, people outside your test list will see only the fallback text.

One gotcha: if you create a new provider for Organization scope, it gets a new originator ID. Update the GUID in your flow, or the card will keep working only for you.

Step 3: Build the flow

Create a flow with a manual trigger so you can test it. The whole flow is six actions, and you do not need an Apply to each. A Select action already loops over every item, so one run produces one email with all rows.

3.1 Get items

Add the SharePoint Get items action and point it at your list.

3.2 Select: Select Card Rows

• From: body('Get_items')?['value']

• Map: switch the map to the Expression tab and paste the following. Building the row as an expression avoids the designer rejecting escaped JSON.

concat(
'{"type":"ColumnSet","separator":true,"columns":[',
'{"type":"Column","width":"2","items":[{"type":"TextBlock","text":"', replace(string(item()?['Title']),'"','\"'), '"}]},',
'{"type":"Column","width":"1","items":[{"type":"TextBlock","text":"', string(item()?['Age']), '"}]},',
'{"type":"Column","width":"2","items":[{"type":"TextBlock","color":"',
if(equals(item()?['WorkType']?['Value'],'Remote'),'Good',if(equals(item()?['WorkType']?['Value'],'Hybrid'),'Warning','Accent')),
'","text":"', string(item()?['WorkType']?['Value']), '"}]}',
']}'
)

Each item becomes one string of JSON describing a row. The color value gives a visual cue: green for Remote, amber for Hybrid, blue for On Site. Outlook cards cannot draw real colored pills, so text color is the closest option.

3.3 Compose: Compose JSON

In the Compose action, use the Expression tab and paste this. Replace the GUID with your own originator ID.

concat(
'{"type":"AdaptiveCard","version":"1.0","originator":"YOUR-ORIGINATOR-ID","body":[',
'{"type":"TextBlock","size":"Large","weight":"Bolder","text":"Sample Adaptive Card"},',
'{"type":"TextBlock","wrap":true,"isSubtle":true,"text":"Here is the current team list."},',
'{"type":"ColumnSet","columns":[{"type":"Column","width":"2","items":[{"type":"TextBlock","weight":"Bolder","text":"Name"}]},{"type":"Column","width":"1","items":[{"type":"TextBlock","weight":"Bolder","text":"Age"}]},{"type":"Column","width":"2","items":[{"type":"TextBlock","weight":"Bolder","text":"Work Type"}]}]},',
join(body('Select_Card_Rows'), ','),
']}'
)

The join call stitches all the row strings together with commas. Notice the card uses version 1.0 elements only. Outlook's actionable messages do not support newer elements such as the Table element, which is why the layout is built from column sets.

3.4 Compose: Compose HTML

Type this as plain text, not an expression:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="application/adaptivecard+json">@{outputs('Compose_JSON')}</script>
</head>
<body>
<p>Here is the current team list.</p>
</body>
</html>

The action name in outputs('Compose_JSON') must match your Compose action. Power Automate replaces spaces in action names with underscores.

3.5 Send an email (V2)

• To: your own address first

• Subject: Sample Adaptive Card

• Body: the output of Compose HTML, with Is HTML set to Yes. If the card does not show up, paste the HTML into the body's code view instead, so you can see what the editor does to the script tag.

The account behind the connection must match the sender you registered in Step 2.

Step 4: Test it

1. Run the flow and open the run history. Copy the output of the JSON Compose into any JSON validator. If it parses, the card is valid.

2. Open the email in Outlook on the web or the new Outlook. You should see the card with all your list items.

3. If you only see the fallback text, open the message properties. Outlook shows an Actionable Messages processing status. If it says None, Exchange did not process the message at all. Check the troubleshooting list below.

4. Always send a fresh email after you change anything about the provider. Messages already sent are not reprocessed.

Troubleshooting

Symptom

Likely cause

Only the fallback text appears

The originator is wrong, the provider is not approved for that recipient, or the From address does not match the registered sender

It works for you but not a coworker

The provider is still on test-user scope, or you created a new provider and the flow still uses the old ID

Processing status says None

The script tag is missing or the JSON is invalid. Check the message source

The JSON is invalid for one row

A name contains a double quote or a field is empty. The replace in the row expression handles quotes. Test your data

Recipient is not on Exchange Online

Actionable messages are only processed for Exchange Online mailboxes

Card appears in one Outlook app but not another

Try Outlook on the web first, since some clients and older versions show only the fallback

Treat any URL that contains a key or signature as a secret. Do not paste those into screenshots or videos.

What's next

In part two I add a comments box and a Submit button. The button is an HTTP action defined in the card itself. When someone clicks it, Outlook sends a request to a Power Automate flow with the comment, and the card can update itself to show the submission was received. Subscribe or follow to catch it.

Collaborative publishing

Build on this work

The author has not enabled new contributions for this item.

Discussion (0 comments)

Join the Discussion

Login to share rich-text comments and reply to other members.

No comments yet. Be the first to share your thoughts!