Rich replies in chat

About 10 minutesNo code neededUpdated July 2026

Instead of describing your pricing in a wall of text, your agent can show a pricing card. Instead of asking for details across five awkward turns, it can show a form. This page shows you how to build these rich replies — called components — by describing what you want.

Before you start, make sure you have:
A Qalyb agent to attach the component to — if you don't have one, follow Create your first agent (5 minutes)
An idea of what you want to show — a pricing card, a booking form, an order tracker

A component is a piece of interactive UI your agent can drop straight into a chat or website-widget conversation — a card, a form, a chart, a live order tracker. You build it once, attach it to one or more agents, and each agent decides on its own when the moment is right to show it. Components live under Library in the dashboard sidebar.

Who can do what:
both admins and members can create, edit, and duplicate components; only admins can delete. Components are available to every role on every plan, and building them with AI doesn't use credits.

Build your first component

Open the Components page

In the sidebar, open Library → Components. You'll see two tabs: My components (the ones your organization owns) and Templates (ready-made starters anyone can copy).

app.qalyb.ai/components
Screenshot: the Components library showing the My components tab in list view with Name and Updated columns and a row actions menu
The Components library — My components tab, list view.
Start from a template — or from scratch

The fastest start is the Templates tab: each card shows a live mini-preview of the real component. Click one to see it full size (with a light/dark toggle), then click Use template — it's copied into your organization and opens in the editor, yours to customize. Prefer a blank slate? Click New component at the top right instead.

Describe what you want

A new component opens on the AI Builder tab — a chat where you describe the component and it gets built for you. Pick one of the starter cards (Pricing table, Order tracker, Product card, Contact form) or type your own, like "a class-booking card with a date picker and a Reserve button". Press Enter to send (Shift+Enter for a new line).

app.qalyb.ai/components/new
Screenshot: the AI Builder tab empty state showing four starter prompt cards and a message composer
The AI Builder empty state. Pick a starter or describe the component you want.
Watch it appear, then keep refining

The builder creates the whole component — layout, data, even the name and icon — and the live preview on the right updates. Keep chatting in the same thread: "make the button blue", "add an email field". Each message edits the current component rather than starting over.

If generation fails:
the builder retries once automatically. If you see "Sorry — I could not generate that. Please try rephrasing.", reword your description and send it again.
Check it in context

Above the preview, switch between Alone, Web widget, and Agent chat — plus light and dark — to confirm it looks right everywhere it might appear.

Save and attach it to your agent

Click Save, then Attach to agents in the top bar. A dialog lists every agent in your organization with an on/off toggle — each toggle takes effect immediately.

app.qalyb.ai/components/new
Screenshot: the Attach to agents dialog listing organization agents each with an attach toggle, one enabled
Attach the component to any agents that should be able to show it.
Tip:
if the component is brand new, Attach to agents saves it for you first automatically.

How your agent decides when to show it

Once attached, the component becomes something the agent can choose to render — in chat and in the website widget. The agent reads the component's name and description to know when it fits: a pricing card when someone asks to compare plans, a booking form when they want an appointment. Write the description with that in mind. Detaching removes the link; deleting a component removes it from all agents.

The starter templates

Qalyb ships eleven starter templates, including:

TemplateWhat it is
Lead capture, Book a demoForms that collect details and hand them back to the agent.
Product card, Cart summary, Pricing planCommerce-style cards for showing items, carts, and tiers.
Order tracker, Class booking, Weather cardStatus and booking widgets with dynamic, data-driven content.
Stats overview, SHC service menu, SHC property cardDashboards and industry-specific (real-estate) layouts.

Managing your library

  • Search filters components by name and description.
  • The list/grid view toggle near the search box works like other dashboard pages — your preference is remembered per browser.
  • Each component's ... menu offers Duplicate (creates a copy named <name> copy and opens it) and Delete (admins only, with a confirm dialog — the component is archived, not destroyed).

Inside the editor

The editor is a full-screen split pane: a live preview on the right, and five authoring tabs on the left. The top bar holds the name (click to rename), Attach to agents, and Save. Most people never leave the AI Builder tab — the others are there when you want direct control:

app.qalyb.ai/components/new
Screenshot: the component editor split pane with the Code tab showing DSL tree JSON and a live preview on the right
The editor: authoring tabs on the left, a live multi-context preview on the right.
TabWhat it's for
AI BuilderBuild and edit the whole component by describing it. The default tab.
CodeThe component's layout, as editable JSON.
SchemaThe shape of the data the agent fills in, plus example data for the preview.
FunctionsWhat buttons, links, and forms do when clicked or submitted.
StatesAlternate looks the component can switch between (e.g. loading, done).

Each tab (apart from the AI Builder) has a collapsible "What is…" help panel with a worked example. The JSON editors check your input as you type, showing a green Valid or red Invalid badge — invalid JSON is kept as text but not applied until it parses.

Making buttons and forms do something

Buttons, links, and forms do nothing until you wire them to a function on the Functions tab. Six types are available:

TypeWhat it does
Set variablesRemembers values inside the component (e.g. which plan was picked).
Send messageSends text back to the agent, so it knows what the customer just did.
Call APICalls a web address on your systems — securely, through Qalyb's server, so your secrets never reach the customer's browser.
Open linkOpens a URL, in a new tab or the same one.
DismissCloses the component.
Run codeCustom client-side code — visible in the editor but not active yet (see below).
app.qalyb.ai/components/new
Screenshot: the Functions tab with a Call API function expanded showing method, endpoint and collapsible headers, query, body, on-success and on-failure sections
A Call API function — method, endpoint, and what to do on success or failure.
Run code is disabled at runtime:
the Run code type appears in the editor but currently does nothing when the component runs — the editor itself labels it "currently disabled at runtime."

For developers

Under the hood a component is a declarative JSON tree (a small DSL) plus a typed data contract. The Code tab holds the tree — nodes of { component, props?, children? } drawn from a fixed registry of about two dozen primitives: layout (Card, Box, Row, Col, Grid), text (Title, Text, Badge, KeyValue), media (Image, Icon, Embed), input (Form, Input, Select, Checkbox), actions (Button, Link), data (Stat, BarChart, LineChart, Table, ProgressBar, Rating), and control (State, Repeat).

tree.json · json
{
  "tree": {
    "component": "Card",
    "children": [
      { "component": "Title", "props": { "text": "{{plan.name}}" } },
      { "component": "Stat", "props": { "value": "{{plan.price}}", "label": "/month" } },
      {
        "component": "Button",
        "props": { "label": "Choose plan", "onClick": "selectPlan" }
      }
    ]
  }
}
Unknown primitives are dropped silently:
a component name or prop that isn't in the registry renders nothing — there is no error. To embed a website, map, 360° tour, or video, use the Embed primitive (a sandboxed iframe), never a raw <iframe> string.

Any string prop or child can interpolate data with {{path}} templates — for example {{plan.name}} — resolved against the merged data (default data plus state variables). For non-string values, use { $bind: 'path' }. The Schema tab declares the data's shape as JSON Schema:

dataSchema.json · json
{
  "type": "object",
  "properties": {
    "plan": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "price": { "type": "string" }
      },
      "required": ["name", "price"]
    }
  },
  "required": ["plan"]
}

The data schema matters beyond preview: attaching a component to an agent creates a synthetic tool on that agent named render_component_<slug>, whose parameters are exactly this schema. The component's description (plus any optional when-to-use instructions) becomes the tool description. When the model calls the tool with data, Qalyb renders the component inline — in both chat and the web widget. A precise schema means the agent passes precise data.

A new component has no id until its first Save (a POST that then swaps the URL to /components/[id]; later saves are PATCH updates). Generation is one endpoint:

curl · bash
curl -X POST https://api.qalyb.ai/components/generate \
  -H "Authorization: Bearer sk-live-..." \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A pricing table with three tiers and a Choose plan button on each",
    "current": null
  }'

On invalid output, generation makes one automatic repair attempt (re-feeding the model its own output plus the validation error). Attachments are managed over the API too:

curl · bash
curl -X POST https://api.qalyb.ai/components/cmp_abc123/agents \
  -H "Authorization: Bearer sk-live-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agt_abc123",
    "instructions": "Render this when the user asks to compare pricing."
  }'
Note:
the optional instructions field (when-to-use guidance, up to 2,000 characters) is folded into the tool description, but it isn't yet surfaced as an input in the attach dialog.

Call API functions go through POST /components/proxy, which is SSRF-guarded: only http/https, with localhost, private IP ranges, and cloud metadata hosts blocked, and an eight-second timeout. Use {{response.*}} in the on-success and on-failure variables to read the result back into component state. Note the structured Functions editor only exposes string values — for richer values, author the function in raw JSON.

Was this guide helpful?