AI Knowledge & Logic

Chat UI from Actions

Return cards, confirmations, order tracking, products, quick replies and charts from a custom action, and the web chat shows them under the bot's reply.

A custom action can return more than data for the bot. It can also return UI for the customer: a card with a subscription's details, a "Cancel order #1042?" confirmation with two buttons, a shipment's tracking, a few products. The web chat draws it under the bot's reply, the way an app would, instead of leaving the bot to describe it in prose.


Where it shows

  • Only in web chat with the new chat experience on ("New chat experience" in the web chat deployment settings). Email, phone, other messengers and the classic widget never get it. Octocom drops it for them, so the same action works on every channel without checking which one it runs on.
  • The bot never sees it. It reads the rest of your result as usual. Keep returning the facts it needs to answer: on every other channel, the bot's answer is all the customer gets.
  • Its colors follow the chat. Cards use the bot message colors and their buttons the customer message colors, unless you set Cards & Buttons colors in the web chat settings.

Returning UI

Add an octocom_ui key to the object your action returns, holding one item or a list of up to 6 items. Every item has a type and the fields listed under Item reference.

Python action:

def execute_action(context):
    sub = fetch_subscription(context["args"]["email"])

    return {
        "subscription": sub,  # what the bot reads
        "octocom_ui": [       # what the customer sees
            {
                "type": "card",
                "title": sub["plan_name"],
                "subtitle": "Active subscription",
                "fields": [
                    {"label": "Next delivery", "value": sub["next_date"]},
                    {"label": "Price", "value": f"{sub['price']} EUR / month"},
                ],
                "buttons": [
                    {"label": "Manage", "url": sub["portal_url"]},
                    {"label": "Skip next delivery", "message": "Skip my next delivery"},
                ],
            }
        ],
    }

Python actions can also use the show_card and ask_confirmation helpers, which add the same items for you.

API action: the endpoint you call answers with the key at the top level of its JSON body. This is useful when the endpoint is your own:

{
  "orderId": "1042",
  "status": "in_transit",
  "octocom_ui": {
    "type": "orderTracking",
    "orderId": "1042",
    "courier": "DPD",
    "trackingNumber": "05212345678901",
    "trackingUrl": "https://tracking.dpd.de/05212345678901",
    "estimatedDeliveryAt": "2026-10-09"
  }
}

Only a top-level octocom_ui counts. Nested keys, and actions that return a list or plain text, are left alone.


Item reference

Field names are case-sensitive. Optional fields can be left out or set to null. URLs must start with https:// or http://. Dates are ISO 8601 ("2026-10-09" or "2026-10-09T14:30:00Z").

card

A title, label/value rows and up to three buttons. Use it for anything with a few facts: a subscription, a booking, a loyalty balance, a warranty.

FieldTypeRequiredNotes
titlestringyesMax 160 characters
subtitlestringnoMax 240
imageUrlURLnoShown across the top
fieldslistnoUp to 12 {"label": string, "value": string or number}; label max 60, value max 240
buttonslistnoUp to 3. {"label", "url"} opens a link. {"label", "message"} sends message as the customer's reply. Label max 40, message max 200. The first link button is filled

confirmation

A question with two buttons, for anything the customer should agree to before it happens. The tapped button is sent as the customer's reply, and the bot acts on that reply on its next turn. Showing a confirmation changes nothing by itself, so do the change in a separate action once the customer has confirmed.

FieldTypeRequiredNotes
titlestringyesWhat will happen, e.g. "Cancel order #1042?". Max 160
descriptionstringnoDetails, e.g. the refund amount. Max 400
confirmLabelstringyese.g. "Yes, cancel it". Max 40
cancelLabelstringyese.g. "No, keep it". Max 40
confirmMessagestringnoSent instead of confirmLabel when tapped. Max 200
cancelMessagestringnoSent instead of cancelLabel when tapped. Max 200
destructivebooleannoRed confirm button for things that can't be undone

The buttons only work while the confirmation is the bot's latest message. Once the customer answers, it stays on screen with their choice marked.

orderTracking

A shipment's progress: status, a drawn route, arrival date, courier and tracking number, the courier's latest scans and the items.

FieldTypeRequiredNotes
orderIdstring/numberyesShown as "Order …"
stagestringnoordered, shipped, outForDelivery, delivered, cancelled or problem. Left out: delivered if deliveredAt is set, shipped if there is a tracking number or shippedAt, otherwise ordered
statusTextstringnoYour own wording, shown for cancelled and problem. Max 120
courierstringnoMax 60
trackingNumberstringnoCan be copied by the customer. Max 80
trackingUrlURLnoThe "Track package" button
orderUrlURLnoThe "View order" button, used when there is no trackingUrl
destinationstringnoCity and country only, e.g. "Vilnius, LT". Never the street. Max 120
orderedAtdateno
shippedAtdateno
estimatedDeliveryAtdateno"Arriving …"
deliveredAtdateno"Delivered …"
eventslistnoUp to 8 {"description", "location"?, "at"?}, newest first
itemslistnoUp to 10 {"name", "quantity"?, "imageUrl"?}

You don't need this for the built-in order lookups (getOrderDetails…): they already show a tracking card. Use it when orders come from a system of your own.

products

Product cards with photo, name, price and a link. The built-in catalog search already shows products from your synced catalog. Use this for products from elsewhere, e.g. a bundle your API builds.

FieldTypeRequiredNotes
productslistyes1 to 10 products, see below
currencystringnoPrinted next to prices, e.g. "€" or "SEK"

Each product: name (required), id, url, imageUrl, price, compareAtPrice (the price before discount; the discount badge is worked out from it), inStock (default true), note (one line on why it fits, max 120).

quickReplies

Up to 4 tap-to-send replies under the message, e.g. {"type": "quickReplies", "options": ["Yes", "No"]}. Each option is max 40 characters and is sent as the customer's own message.

chart

A small bar or line chart.

FieldTypeRequiredNotes
kindstringnobar (default) or line
titlestringnoMax 120
labelslistyes1 to 24 x-axis labels
serieslistyes1 to 4 {"name", "values"}, with one number per label
unitstringnoAppended to values, e.g. "cm". Max 12

On this page