Render spec & widgets

Last updated  Aug 4, 2026

The agent answers in two registers at once: a line to speak, and a short list of widgets to draw. The SDK renders what it is handed.

Both halves come out of a single model call. The agent writes the spoken answer, then a separator, then a JSON array of widgets, and the engine splits them apart before streaming. That is why the voice and the visuals never disagree — they were written together.

Anatomy of a spec

speak is the hero answer: voiced on a voice turn, shown as text on a typed one. Everything else is optional.

Render spec
{  "speak": "Your settleable balance is 42,150 EGP, up 8% on last week.",  "widgets": [    {      "type": "stat",      "label": "Settleable",      "value": "42,150 EGP",      "delta": "+8.2%"    },    {      "type": "progress",      "label": "Payouts cleared",      "value": 0.62    }  ],  "follow": "Want me to settle it now?",  "meta": {    "conversationId": "conv_7Zp3Kd10",    "direction": "ltr"  }}

follow becomes a tap-to-send pill, so the obvious next question costs one tap instead of a sentence. meta.direction lets an Arabic answer lay itself out right-to-left without the client guessing.

Widget catalogue

Thirteen kinds, each with a native implementation on every platform. An unrecognised kind degrades to the spoken answer rather than breaking the turn, so adding a kind never bricks an older app.

KindRendersReach for it when
statA single figure with an optional deltaOne number is the answer.
progressA labelled barSomething is partway between two states.
listRows with title, subtitle, trailing valueSeveral comparable items.
cardA titled block of key–value detailOne record, examined closely.
chartA small series plotThe shape over time is the point.
markdownFormatted rich textThe answer is prose that needs structure.
mediaAn image or short clipShowing beats describing.
confirmA summary plus approve and cancelThe next step changes data or moves money.
productsA product row with quantity steppersThe user is assembling an order.
ticketA support-ticket summaryThe turn ends in a case rather than an answer.
callbackA request-a-call affordanceA human should take it from here.
csatA satisfaction promptClosing the loop on a resolved request.
customA payload your app renders itselfYou need a shape we do not ship.
confirm is the only widget that can change something. Action tools never run inside a turn — they short-circuit into a confirm card, and the action itself runs only after the user approves it. High-risk actions additionally require the device biometric gate.

Theming

One accent pair, an appearance, and a radius. There is no stylesheet to maintain and no design handoff — the same spec renders in your brand on every platform.

AppDelegate.swift
let theme = VoqalTheme(  accent: "#2D5BFF",  accent2: "#5EC5F1",       // gradient pair end  appearance: .auto,       // .light | .dark | .auto  radius: 20)var configuration = VoqalSDKConfiguration(requestId: requestId, theme: theme)VoqalSDKManager.shared.setup(configuration: configuration)

Answers & data

stat

A headline number with delta and context.

One number is the answer — balances, totals, counts.

Available balanceEGP 48,250+12.4% vs last week
chart

A compact series plot the agent aggregates.

The shape over time is the point.

list

Rows with titles, statuses, and trailing amounts.

Several comparable items — transactions, orders.

Recent transactions

Order #10428

Card · 10:24

EGP 1,250

Order #10427

Wallet · 09:58

EGP 480

Order #10426

Card · 09:12

EGP 2,100

Refund #R-882

Card · 08:40

−EGP 300
card

A titled block of key–value detail with a status badge.

One record, examined closely.

Payment linkActive
AmountEGP 750.00
ReferenceINV-2048
Expires24 Jul 2026

Share this link to collect payment.

Commerce & progress

products

Product rows with photos, prices, and quantity steppers.

The user is assembling an order.

Fresh picks

Juhayna Full Cream Milk

400 g

24EGP
0

Free-range eggs

10 pcs

62EGP
0
progress

A labelled multi-step bar with the active stage.

Something is partway between two states — settlements, refunds, deliveries.

Settlement in progress~2h
ProcessingStep 2 of 3

Actions

confirm

A summary plus approve and cancel controls.

The next step changes data or moves money. High-risk actions add Face ID.

Request instant settlement
AmountEGP 48,250
FeeEGP 0
Arrives~2 hours
TotalEGP 48,250

Preview — confirm runs live in your app.

callback

A completed action handed back as something shareable.

The turn ends with an artifact — a link, a booking, a receipt.

We'll call you back

A settlement specialist will call the number on file.

~15 min

Support & content

ticket

A structured support-ticket summary.

The turn ends in a case rather than an answer.

Support ticketIn progress
Chargeback under review#8842
Resolves in 2 business days
csat

A lightweight satisfaction prompt.

Closing the loop on a resolved request.

How did we do?

markdown

Formatted rich text.

The answer is prose that needs structure.

Your instant settlement is enabled. Payouts arrive within 2 hours on business days.

  • No extra fee under EGP 50,000
  • Available 7 days a week

The accent drives the voice orb, the highlights, and the primary buttons; accent2 is the far end of every gradient and falls back to the accent when you leave it out.

Rules of the spec

A few constraints keep answers readable and keep voice and screen in agreement:

  • One confirm card per turn. If the agent has already produced a confirm, it must not also author a duplicate detail card describing the same action.
  • The spoken line never names the confirmation method. It says what will happen, not which gesture will approve it — the device decides that.
  • Widgets support the answer; they do not repeat it. If speak already gave the number, the stat widget is there to make it scannable, not to say it twice.
  • Keep the array short. Three widgets is a rich answer; ten is a dashboard nobody asked for.
© 2026 VoqalVoqal SDK & engine documentation