Render spec & widgets
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.
{ "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.
| Kind | Renders | Reach for it when |
|---|---|---|
stat | A single figure with an optional delta | One number is the answer. |
progress | A labelled bar | Something is partway between two states. |
list | Rows with title, subtitle, trailing value | Several comparable items. |
card | A titled block of key–value detail | One record, examined closely. |
chart | A small series plot | The shape over time is the point. |
markdown | Formatted rich text | The answer is prose that needs structure. |
media | An image or short clip | Showing beats describing. |
confirm | A summary plus approve and cancel | The next step changes data or moves money. |
products | A product row with quantity steppers | The user is assembling an order. |
ticket | A support-ticket summary | The turn ends in a case rather than an answer. |
callback | A request-a-call affordance | A human should take it from here. |
csat | A satisfaction prompt | Closing the loop on a resolved request. |
custom | A payload your app renders itself | You 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.
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
statA headline number with delta and context.
One number is the answer — balances, totals, counts.
chartA compact series plot the agent aggregates.
The shape over time is the point.
listRows with titles, statuses, and trailing amounts.
Several comparable items — transactions, orders.
cardA titled block of key–value detail with a status badge.
One record, examined closely.
Commerce & progress
productsProduct rows with photos, prices, and quantity steppers.
The user is assembling an order.
progressA labelled multi-step bar with the active stage.
Something is partway between two states — settlements, refunds, deliveries.
Actions
confirmA summary plus approve and cancel controls.
The next step changes data or moves money. High-risk actions add Face ID.
callbackA completed action handed back as something shareable.
The turn ends with an artifact — a link, a booking, a receipt.
Support & content
ticketA structured support-ticket summary.
The turn ends in a case rather than an answer.
csatA lightweight satisfaction prompt.
Closing the loop on a resolved request.
markdownFormatted rich text.
The answer is prose that needs structure.
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
speakalready 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.
