Docs

Channel Delivery Templates

When an Agentic Flow agent sends a message through a channel, a delivery template controls what that message looks like. Templates are configured on the Output node in the flow editor, once Channel Delivery is turned on.

You have three options — leave the template empty, write a fixed message, or write a template with placeholders. The right choice depends on how much control you need over the output.

Quick Decision Guide

Do you know what the message should look like?

  • Yes, same every time → write a fixed template with no placeholders. The agent is not involved.
  • Yes, but the details change → write a template with placeholders. You define the layout; the agent fills in the values.
  • No, let the agent decide → leave the template empty. The agent writes the full message. For more control over when to deliver, set Invocation to agentic.

Is this a HITL approval card or regular delivery?

  • HITL approval → template must include Approve and Reject buttons. Only the 7 tokens in the HITL placeholders table are substituted.
  • Regular delivery → no button requirement. Any placeholder token works; the agent fills it in.

Which channels support structured templates?

  • Adaptive Cards — Microsoft Teams only (adaptive_card event type).
  • Email — Outlook (email, email_reply event types). The template is a JSON object with subject and body.
  • Plain messages — Telegram, Facebook, Universal Webhook, and Google Chat (message event type) deliver the agent’s response as text. The template is not applied to message events.

The Delivery Targets Table

Open a flow in the Agentic Flow editor, select the Output node, and turn on Channel Delivery. The Delivery Targets table appears, with one row per destination.

ColumnDescription
ChannelWhere the message goes (Teams, Outlook, Telegram, etc.).
Channel TypeAuto-filled from the channel you select.
Route TypeAuto-filled (conversation, notification, etc.).
Event TypeThe kind of message: adaptive_card, message, email, etc. For HITL rows this is locked to hitl_approval.
RecipientWho receives it. Pick a named contact, or use auto to let the system resolve the recipient.
TemplateThe message layout in JSON. Paste an Adaptive Card or email template here.
Invocationautomatic — fires on every invocation. agentic — the agent decides whether and to whom to deliver. Default: automatic.

With automatic invocation, the Template column appears after you have selected a channel and event type for that row. With agentic invocation, it appears as soon as the row exists.

The Template Editor

Click the </> icon (Open template editor) next to the Template column header. The editor matches the row’s event type:

EditorOpens forPreview
HITL Adaptive Card Templatehitl_approval rowsAdaptive Card
Delivery Adaptive Card TemplateOther card rows, such as adaptive_cardAdaptive Card
Email Delivery Templateemail and email_reply rowsEmail

In each editor you can:

  • Write or paste the template JSON. It is validated as you type, and Save template is blocked until the template is valid or empty.
  • Load a built-in example with Use example, or Copy it from the Example panel.
  • Remove the template with Clear.
  • Check the live preview, which shows the template with sample values for placeholders. Click refresh to re-render it. The preview is hidden while the template is invalid, and shows Preview unavailable if the card cannot be rendered.

The HITL and email editors also list the placeholders they substitute.

Note

The live preview is a structural check, not a pixel-perfect render. Channels apply their own theme and button chrome at send time. Use the preview to verify structure and content, not exact styling.

Three Ways to Write a Template

Option A — Leave it empty

For message events, the agent’s response is sent as a plain message. For adaptive_card and email events, the agent writes the full card or email itself. Best when you want the agent to fully control the output.

Option B — Fixed message (no placeholders)

Your JSON is sent exactly as written on every invocation. The agent is not involved. Use this for messages that always look the same — daily status cards, fixed notifications.

Option C — Template with placeholders

Define the layout using {{token}} placeholders. The agent (or the system, for HITL cards) fills in each token at run time. The structure and wording stay exactly as you wrote them; only the placeholder values change.

Allowed Placeholders

HITL Templates

Only the following 7 tokens are substituted in approval cards. Any other {{token}} appears as literal text in the delivered card.

TokenWhat it showsExample
{{title}}Headline from the Approval Title field.Action Required
{{description}}Short explanation from the Approval Description field.Please review before sending.
{{bot_response}}The agent’s proposed response — the approver can edit this before approving.Hi! Your refund of $42 has been processed.
{{execution_id}}Internal ID used to resume the flow after a decision.f87a3d0f-0c66-4c1b-8f30-e082297be365
{{original_message}}The user message that triggered the flow.Can you refund my last order?
{{sender_name}}Display name of the user who sent the original message.Alex Tan
{{source_channel}}The channel the original message came from.microsoft_teams

Output Templates

For regular delivery, placeholders are filled by the agent. You can use any token name and the agent will populate it with a contextually appropriate value. The email editor lists these common tokens:

TokenWhat it shows
{{title}}A short headline derived from the agent’s response.
{{bot_response}}The full agent response.
{{sender_name}}Display name of the user who started the conversation.
{{source_channel}}The channel the original message came from.
Any custom token{{priority}}, {{amount}}, {{order_id}}, etc. — the agent fills these in based on the conversation context.

Tip

To prevent a token from being substituted, write it as plain text without {{ }}.

Template Examples

Example 1 — HITL Approval Card

An approval card for a Human-in-the-Loop flow. Includes the original message, a proposed response the approver can edit, and Approve/Reject buttons.

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "Container", "style": "accent", "bleed": true,
      "items": [
        { "type": "TextBlock", "text": "⚠ {{title}}",
          "size": "Large", "weight": "Bolder", "color": "Warning", "wrap": true },
        { "type": "TextBlock",
          "text": "From {{sender_name}} via {{source_channel}}",
          "size": "Small", "isSubtle": true, "spacing": "None" }
      ]
    },
    { "type": "TextBlock", "text": "{{description}}", "wrap": true, "spacing": "Medium" },
    { "type": "TextBlock", "text": "💬 {{original_message}}", "wrap": true, "spacing": "Medium" },
    { "type": "Input.Text", "id": "edited_response",
      "placeholder": "Edit the response before approving…",
      "isMultiline": true, "value": "{{bot_response}}" },
    { "type": "TextBlock", "text": "Ref: {{execution_id}}",
      "size": "Small", "isSubtle": true, "spacing": "Small" }
  ],
  "actions": [
    { "type": "Action.Submit", "title": "✅ Approve & Send",
      "style": "positive", "data": { "hitl_action": "approve" } },
    { "type": "Action.Submit", "title": "Reject",
      "style": "destructive", "data": { "hitl_action": "reject" } }
  ]
}

Example 2 — Output Delivery Card

A delivery card for the Output node. No approve/reject buttons — just a formatted message.

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "Container", "style": "emphasis", "bleed": true,
      "items": [
        { "type": "TextBlock", "text": "{{title}}",
          "size": "Large", "weight": "Bolder", "wrap": true }
      ]
    },
    { "type": "TextBlock", "text": "{{bot_response}}", "wrap": true, "spacing": "Medium" },
    { "type": "TextBlock", "text": "Sent via {{source_channel}}",
      "size": "Small", "isSubtle": true, "spacing": "Small" }
  ]
}

Example 3 — Empty template

Leave the template field blank. On a message event, the agent’s response is sent as plain text. Best for short, conversational replies.

Example 4 — Fixed card (no placeholders)

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    { "type": "TextBlock", "text": "Daily summary ready.",
      "weight": "Bolder", "size": "Medium", "wrap": true }
  ]
}

Sent exactly as written on every invocation. No placeholder substitution, no agent involvement.

Validation

The system validates your template when you save a delivery target row.

HITL templates — save is blocked unless all four checks pass:

CheckWhat it means
Valid JSONThe template must be parseable JSON.
"type": "AdaptiveCard"The root object must be an Adaptive Card.
Approve action presentThe template must include an Approve button.
Reject action presentThe template must include a Reject button.

Delivery card templates — only valid JSON and "type": "AdaptiveCard" are required.

Email templates — must be a JSON object that includes subject and body.

An empty template is always valid.

If you use a token not in the HITL allowed list, you can still save. The token appears as literal text in the delivered card.

HITL Configuration

HITL (Human-in-the-Loop) pauses a flow and sends an approval request to a reviewer before any message is delivered. Use it for high-impact actions — emails to customers, payments, anything that touches another system.

In an Agentic Flow, the approval card is configured in the Approval Delivery Targets table of the Human In The Loop node. For AI Coworkers, set the approval delivery target on the Governance tab. See Human in the Loop for how approvals work.

Template rules:

  • The template must include at least one Approve button and one Reject button.
  • Tracking IDs (execution ID, approver identity) are added to each button automatically — you do not need to include them.
  • Only the 7 tokens in the HITL placeholders table are substituted. Anything else appears as literal text.
  • If the template is empty or invalid, the system uses a default card with Approve and Reject buttons only.

After approval: The flow resumes. If the approver edited the edited_response field, that text is used as the delivered message. If not, the original {{bot_response}} value is used.

After rejection: The flow resumes with a rejection signal and the proposed response is not sent.

Note

The HITL template controls the approval card sent to the reviewer. The Output node’s template controls the final delivered message to the end user. These are separate templates on separate nodes.