FlowLibs
Browse Cloud FlowsConnectorsAI ToolsDev ToolsPricingAboutContact
Dev Tools/Adaptive Cards

Adaptive Cards

Author Adaptive Cards that render as native UI in Teams, Outlook, and bots. A live card designer with a JSON editor and starter gallery, plus filterable cheat sheets for every element, container, input, and action — and the rules for posting cards from Power Automate and embedding them in Outlook actionable messages.

Adaptive Cards18 min read·Updated 2026-06-16
Adaptive CardsTeamsOutlookActionable MessagesPower AutomateAction.SubmitAction.ExecuteFactSetInput.ChoiceSetJSON
Card designer

Requester header, FactSet, and Approve / Reject submit actions — the classic “wait for a response” card.

Leave request
Priya Nair
Priya Nair
Submitted today
TypeAnnual leave
DatesJun 18 – Jun 20 (3 days)
CoverDana Wu

Preview approximates the default host config. Inputs and actions don’t submit; Action.ShowCard expands inline. Use the official Adaptive Cards Designer for pixel-exact, full-schema rendering.

On this page

  • What Adaptive Cards are
  • Card anatomy
  • Elements
  • Containers & layout
  • Inputs (collecting data)
  • Actions
  • Posting from Power Automate
  • Outlook actionable messages
  • Templating & data binding
  • Versions & host support
  • Styling, accessibility & gotchas

What Adaptive Cards are

An Adaptive Card is a chunk of UI described in JSON. You author the card once; each host — Microsoft Teams, Outlook, a bot, Copilot Studio, Viva Connections — renders it as native UI that adapts to its own look and feel. No HTML or CSS, no per-client tweaking: the same payload becomes a Teams message, an email card, or a bot reply.

Every card is an object with type: "AdaptiveCard", a version, a body array of elements, and an optional actions array of buttons. The host supplies the styling (fonts, colours, spacing) through a host config, so you describe *intent* (“this is a heading”, “this is an accent button”) rather than pixels.

  • Teams — flow-bot messages, bot replies, message-extension and dialog (task module) UI. Supports schema 1.5.
  • Outlook actionable messages — a card embedded in an email so recipients act without leaving the inbox. Separate, more conservative schema track (baseline 1.0).
  • Power Automate — posts cards to Teams (display-only or “wait for a response”) via the Teams connector.
  • Bots / Copilot Studio / Bot Framework Web Chat — rich replies and forms (Web Chat tracks 1.6).
  • Design + validate in the official Adaptive Cards Designer, then paste the JSON into your flow or bot.

Try the designer above

The designer at the top of this page ships starter cards — approval, notification, form, receipt, and more. Switch to JSON to edit the payload and watch the preview update live, then Copy it straight into a “Post adaptive card” action or an Outlook actionable message.

Card anatomy

Start from this skeleton. type and version are required; $schema enables editor IntelliSense; everything visible lives in body; buttons live in actions.

json
{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.5",
  "body": [
    { "type": "TextBlock", "text": "Order shipped", "size": "Large", "weight": "Bolder", "wrap": true },
    { "type": "TextBlock", "text": "Tracking number TN-4821 is on its way.", "wrap": true, "isSubtle": true }
  ],
  "actions": [
    { "type": "Action.OpenUrl", "title": "Track package", "url": "https://contoso.com/track/TN-4821" }
  ]
}
Minimal card — a heading, a wrapped line of text, and one button.
15/15
PropertyTypeSinceNotes
`type``"AdaptiveCard"`1.0Required. Always the literal string.
`version`string1.0Required. Schema the card needs (e.g. `"1.5"`). Below the host version, `fallbackText` renders instead.
`$schema`uri1.0Editor hint only; ignored at render time.
`body`Element[]1.0Ordered list of elements shown in the card.
`actions`Action[]1.0Buttons in the card’s action bar.
`selectAction`ISelectAction1.1Invoked when the whole card is tapped. `Action.ShowCard` not allowed here.
`backgroundImage`uri / object1.0 / 1.2Background fill; object form adds fillMode + positioning.
`minHeight`string1.2e.g. `"160px"`. Pairs with `verticalContentAlignment`.
`verticalContentAlignment`string1.1`top` / `center` / `bottom` — only for fixed/min-height cards.
`rtl`boolean1.5Right-to-left layout for the whole card.
`lang`string1.02-letter ISO code; localizes date/time functions.
`fallbackText`string1.0Shown (as markdown) when the host is older than `version`.
`refresh`Refresh1.4Auto-refresh via `Action.Execute` (Universal Action Model).
`authentication`Authentication1.4SSO / just-in-time OAuth for Universal Actions.
`metadata`Metadata1.6Non-rendered metadata (e.g. `webUrl`).
Top-level AdaptiveCard properties. Set version to the lowest your target host supports.

Version is a contract, not a wish

The host renders at most the version it supports. Set version to the lowest version whose features you actually use — declaring "1.5" on a card aimed at Outlook (1.0) can blank the card on older clients. Always provide fallbackText.

Elements

Elements are the leaf content you stack in body (or inside a container). TextBlock and Image cover most cards.

6/6
ElementPurposeKey properties
`TextBlock`A run of text (the workhorse).`text`, `wrap`, `size`, `weight`, `color`, `isSubtle`, `spacing`, `horizontalAlignment`, `maxLines`, `style:"heading"`
`RichTextBlock`Mixed inline formatting in one paragraph.`inlines[]` of `TextRun` (`text`, `weight`, `color`, `italic`, `strikethrough`, `selectAction`)
`Image`A single image from a URL.`url`, `altText`, `size` (small/medium/large/auto/stretch), `width`/`height`, `style:"person"`, `horizontalAlignment`, `selectAction`
`Media`Audio / video clip with a poster.`poster`, `sources[]` (`url`, `mimeType`), `altText` (host support varies — Teams yes, Outlook no)
`Icon`A Fluent UI icon (1.6).`name`, `size`, `style`, `color`
`CodeBlock`Monospace, syntax-aware code (Teams ext).`codeSnippet`, `language`, `startLineNumber`
Common card elements and their key properties.

TextBlock honours a small markdown subset across most hosts: **bold**, _italic_, [links](https://…), bulleted / numbered lists, and line breaks. Use wrap: true almost everywhere — text is truncated to one line by default.

json
{
  "type": "ColumnSet",
  "columns": [
    { "type": "Column", "width": "auto", "items": [
      { "type": "Image", "url": "https://contoso.com/avatar.png", "size": "Small", "style": "Person", "altText": "Priya N." }
    ] },
    { "type": "Column", "width": "stretch", "verticalContentAlignment": "Center", "items": [
      { "type": "TextBlock", "text": "Priya Nair", "weight": "Bolder", "wrap": true },
      { "type": "TextBlock", "text": "Requested 3 days of leave", "isSubtle": true, "spacing": "None", "wrap": true }
    ] }
  ]
}
A heading TextBlock plus a person-style avatar image.

Containers & layout

Containers group and arrange elements. Container stacks vertically; ColumnSet lays out side by side; FactSet renders a tidy label/value grid; Table (1.5) draws real rows and columns.

7/7
ContainerPurposeKey properties
`Container`Group elements; tint a region.`items[]`, `style` (default/emphasis/good/attention/warning/accent), `bleed`, `minHeight`, `verticalContentAlignment`, `selectAction`
`ColumnSet`Horizontal row of columns.`columns[]`, `horizontalAlignment`, `spacing`, `style`, `bleed`
`Column`One column within a ColumnSet.`width` (`auto` / `stretch` / number / `"80px"`), `items[]`, `style`, `verticalContentAlignment`
`FactSet`Label/value pairs (e.g. metadata).`facts[]` of `{ "title", "value" }`
`ImageSet`A thumbnail gallery.`images[]`, `imageSize`
`Table`Tabular data with real columns (1.5).`columns[]` (`width`), `rows[]` of `TableRow` → `cells[]` of `TableCell`, `firstRowAsHeaders`, `gridStyle`
`ActionSet`Buttons inside the body, not the action bar.`actions[]`
Layout containers. Most accept style, spacing, separator, and selectAction.

Spacing, separator & bleed

Every element takes spacing (none/small/default/medium/large/extraLarge/padding) controlling the gap above it, and separator: true to draw a divider line above it. bleed: true lets a styled container extend to the card edge, ignoring the card padding — great for coloured headers.

json
{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    { "type": "Container", "style": "Emphasis", "bleed": true, "items": [
      { "type": "TextBlock", "text": "Expense report #1042", "weight": "Bolder", "size": "Large", "wrap": true }
    ] },
    { "type": "FactSet", "facts": [
      { "title": "Submitted by", "value": "Dana Wu" },
      { "title": "Amount", "value": "$486.20" },
      { "title": "Status", "value": "Pending approval" }
    ] }
  ]
}
An emphasis header that bleeds to the edge, then a FactSet.

Inputs (collecting data)

Inputs turn a card into a form. Each input needs a unique `id` — that id becomes the key in the data sent back when the user submits. Pair inputs with an Action.Submit (or Action.Execute) to gather their values.

6/6
InputRenders asKey properties
`Input.Text`Single- or multi-line text box.`placeholder`, `value`, `isMultiline`, `maxLength`, `style` (text/tel/url/email), `regex` (1.3)
`Input.Number`Numeric field.`min`, `max`, `value`, `placeholder`
`Input.Date`Date picker.`min`, `max`, `value` (ISO `YYYY-MM-DD`)
`Input.Time`Time picker.`min`, `max`, `value` (`HH:MM`)
`Input.Toggle`On/off checkbox.`title`, `value`, `valueOn`, `valueOff`
`Input.ChoiceSet`Dropdown, radio, or checkbox list.`choices[]` (`title`/`value`), `style` (compact/expanded), `isMultiSelect`, `value`, `placeholder`
Input elements. All support id, label, isRequired, errorMessage (1.3+), and value.
json
{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    { "type": "Input.Text", "id": "comments", "label": "Comments", "isMultiline": true, "isRequired": true,
      "errorMessage": "Please add a comment." },
    { "type": "Input.ChoiceSet", "id": "priority", "label": "Priority", "style": "Compact", "value": "normal",
      "choices": [
        { "title": "Low", "value": "low" },
        { "title": "Normal", "value": "normal" },
        { "title": "High", "value": "high" }
      ] }
  ],
  "actions": [
    { "type": "Action.Submit", "title": "Send", "style": "positive" }
  ]
}
A small form. The submitted payload will be { "comments": "…", "priority": "high" }.

Inputs only return data on a “wait for response” action

In Power Automate, a plain “Post adaptive card” is display-only — Action.Submit raises an error and you get nothing back. To collect input you must use a “…and wait for a response” action (see below). Validation (isRequired, regex, errorMessage) needs schema 1.3+.

Actions

Actions are the buttons. They sit in the card-level actions array, inside an ActionSet, or as a selectAction on an element. There are six types.

6/6
ActionDoesKey properties / notes
`Action.OpenUrl`Opens a URL.`url`. The only action that works on a *display-only* Teams card.
`Action.Submit`Sends inputs + `data` back to the host/bot.`data` (string or object), merged with all input values.
`Action.ShowCard`Reveals a nested card inline.`card` (an AdaptiveCard). Not allowed as a `selectAction`.
`Action.ToggleVisibility`Shows/hides elements by id.`targetElements[]` (id strings or `{ elementId, isVisible }`).
`Action.Execute`Universal Action — sends to a bot, can return a new card.Since **1.4**. Replaces Submit/Http across Teams + Outlook; needs a bot.
`Action.ResetInputs`Clears input values (Teams).`targetInputIds[]`. Teams-specific.
Action types. style: default / positive / destructive; mode: primary / secondary (overflow).

Universal Action Model (Action.Execute)

Action.Execute (schema 1.4) unifies Teams Action.Submit and Outlook Action.Http into one model that a bot handles and that can return an updated card. For backward compatibility, wrap Action.Execute in an ActionSet and give it a fallback of Action.Submit so older Teams clients still render a button.

Teams drops positive/destructive styling

The Teams host config does not honour style: "positive" / "destructive" on actions — buttons render in the default accent. Don’t rely on colour alone to signal “Approve” vs “Reject”; put it in the button text too.

Posting from Power Automate

The Microsoft Teams connector offers several “Post adaptive card” actions. The split that matters is display-only vs wait for a response:

  • Post adaptive card in a chat or channel / Post your own adaptive card as the Flow bot — display only. Only Action.OpenUrl works; Action.Submit errors.
  • Post adaptive card and wait for a response (to a user or channel) — the flow pauses until someone responds, then exposes each input value as dynamic content for later steps.
  • A card in a *channel* can be answered by anyone in that channel; the flow continues on the first response and ignores the rest.
  • After a response, set Update message (and Should update card) so the card visibly changes — otherwise the form just resets and people may submit again.

Power Automate does NOT support card templating

The ${...} templating language is not evaluated by the Teams connector. Instead, drop Power Automate dynamic content and expressions directly into the JSON values (see the example below). Keep every value in straight double quotes — numbers included — and watch for curly quotes pasted in from Word.

json
{
  "type": "AdaptiveCard",
  "version": "1.4",
  "body": [
    { "type": "TextBlock", "text": "Leave request", "size": "Large", "weight": "Bolder", "wrap": true },
    { "type": "FactSet", "facts": [
      { "title": "Requester", "value": "@{triggerBody()?['requester']}" },
      { "title": "Dates", "value": "@{triggerBody()?['dates']}" }
    ] },
    { "type": "Input.ChoiceSet", "id": "decision", "style": "Expanded", "label": "Decision",
      "choices": [
        { "title": "Approve", "value": "approve" },
        { "title": "Reject", "value": "reject" }
      ] }
  ],
  "actions": [
    { "type": "Action.Submit", "title": "Submit decision" }
  ]
}
Approval card for “…and wait for a response”. Expressions resolve at run time; the choice returns under id "decision".

After the action, the input ids (decision) and a submitActionId are available as dynamic content. Use them to branch the flow — e.g. a Condition on decision equals approve.

Prerequisite: the Workflows app

Flow-bot cards need the Workflows (Power Automate) app installed in Teams. “Card didn’t post” is almost always a missing app, malformed JSON (curly quotes), or an image URL that isn’t publicly reachable.

Outlook actionable messages

Outlook can render an Adaptive Card inside an email so the recipient acts without leaving the inbox. The card JSON is wrapped in a <script> tag in the email’s <head>. Outlook is a separate, more conservative schema track — design for 1.0 and test before using newer features.

html
<html>
<head>
  <script type="application/adaptivecard+json">
  {
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.0",
    "originator": "&lt;your-provider-id-from-the-dashboard&gt;",
    "hideOriginalBody": true,
    "body": [
      { "type": "TextBlock", "text": "Approve expense #1042?", "size": "Large", "weight": "Bolder", "wrap": true }
    ],
    "actions": [
      { "type": "Action.OpenUrl", "title": "Review in browser", "url": "https://contoso.com/expenses/1042" }
    ]
  }
  </script>
</head>
<body>
  <!-- Plain-text/HTML fallback for clients that can't render the card -->
  Approve expense #1042: https://contoso.com/expenses/1042
</body>
</html>
The card is embedded as application/adaptivecard+json in the HTML head. hideOriginalBody hides the fallback markup.
  • The email body must be HTML (plain text can’t carry the <script>), and recipients must be individual mailboxes on Exchange Online / Outlook.com — not groups or shared mailboxes.
  • originator must hold a valid provider ID from the Actionable Email Developer Dashboard whenever you send to anyone other than yourself; without it the card is stripped.
  • Interactive actions historically used Action.Http; the modern path is Action.Execute (1.4+) via a bot on the Outlook Actionable Messages channel.
  • Actions can’t be taken on messages older than ~1 month, and there’s a limit on how many actionable messages render at once.

Legacy auth retired — use Entra ID tokens

Actionable Messages moved from legacy (EAT) authentication to Microsoft Entra ID tokens; the legacy phase-out completed June 8, 2026. Integrations that still rely on legacy tokens no longer function — confirm your action endpoint validates Entra ID bearer tokens.

Templating & data binding

The Adaptive Cards Templating SDK separates layout from data: author a template with ${...} binding expressions, then merge it with a JSON data object at render time. Great for bots and custom apps that bind cards in code.

json
{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    { "type": "TextBlock", "text": "Hello ${user.name}", "weight": "Bolder", "wrap": true },
    { "type": "Container", "$data": "${orders}", "items": [
      { "type": "TextBlock", "text": "${id} — ${status}", "wrap": true,
        "$when": "${status != 'cancelled'}" }
    ] }
  ]
}
A template: ${expr} binds fields, $data repeats a block per array item, $when conditionally includes it.
javascript
import * as ACData from "adaptivecards-templating";

const template = new ACData.Template(cardTemplateJson);
const card = template.expand({
  $root: { user: { name: "Priya" }, orders: [{ id: "A-1", status: "shipped" }] }
});
Binding in code with adaptivecards-templating.

Not in Power Automate

The Teams connector does not evaluate ${...} templating. In flows, bind values with dynamic-content expressions inside the JSON (see the Power Automate section). Reserve ${...} templating for bots / custom code that run the templating SDK.

Versions & host support

Schema support varies by host, so a feature that works in Teams may be ignored in Outlook. Target the version your host supports, and provide fallbacks.

HostSchema versionNotes
Microsoft Teams (desktop, web, mobile)1.5Most common target. No positive/destructive action styling; no file/image upload.
Microsoft 365 Copilot Chat1.5Primary surface for M365 agent scenarios.
Outlook Actionable Messages1.0 (–1.2)Separate track; baseline 1.0. Action.Execute needs 1.4+ via a bot.
Bot Framework Web Chat1.6Action.Execute not supported in Web Chat.
Viva Connections / Webex1.2Adaptive Card Extensions / partner hosts.
Current schema1.6Latest published; adds Icon, metadata, and more.
Approximate schema ceiling per host (verify against current docs — platforms move).
  • `fallbackText` on the card renders when the host is older than version — always set a meaningful sentence.
  • `fallback` on an element/action swaps in a simpler alternative (or "drop") when the host can’t render it — e.g. Action.Execute → Action.Submit.
  • `requires` (1.2) declares a minimum feature version on an element so the host can trigger that element’s fallback.
  • When in doubt, set the Designer’s Target version to your host and let it flag unsupported elements before you ship.

Styling, accessibility & gotchas

  • Describe intent, not pixels. Use size/weight/color/isSubtle and container style tokens; the host config maps them to its theme so cards look native in light and dark mode.
  • Host images on a public HTTPS URL. Outlook and Teams won’t render data-URI / base64 images, and a URL that needs auth shows nothing. Always set altText.
  • Always `wrap: true` on TextBlock, or text clips to one line. Test long values and narrow widths (Teams mobile, meeting side panel).
  • Accessibility: meaningful altText, real label text on inputs (label), and don’t signal meaning with colour alone — Teams ignores button colour styling anyway.
  • Dark mode: container style tokens adapt automatically; avoid hard-coded color hacks. Outlook actionable messages historically don’t restyle for dark mode.
  • Validate the JSON in the Designer before pasting into a flow — most “card didn’t render” issues are curly quotes, a trailing comma, or a missing version.
  • Keep cards short. Long cards get truncated in compact surfaces; link out with Action.OpenUrl for detail rather than cramming everything in.

Build a card library

Save one tested base per scenario — approval, notification, receipt, form — and clone it per flow. The designer above is a starting gallery; copy a template, swap the text/ids, and drop it into your “Post adaptive card” action.

← All Dev ToolsUse these in your AI assistant →
Spotted an error or have a suggestion? Let us know
FlowLibs

A curated library of production-grade Power Automate cloud flow patterns. Packaged as managed solutions, ready to import into your environment.

Library

  • Browse Cloud Flows
  • Approvals
  • Email & Notifications
  • Reporting
  • Security & Compliance

AI

  • AI Tools
  • MCP Server
  • Generate a Token

Resources

  • About
  • FAQ
  • Support
  • Status
  • Contact
  • Power Automate Docs
  • Connector Reference

© 2026 FlowLibs. All rights reserved.

  • Privacy
  • Terms
  • Refunds
  • Cookies
  • Acceptable Use
  • DMCA
Help