uHamkorDocumentation
API Documentation

UI widgets: developer reference

The widget definition (.widget) format, the node tree, function objects, the endpoint contract for call_api, error codes and security rules.

๐Ÿงฐ UI widgets: developer reference

This page describes the stored format of a widget, how its functions talk to your API, and the error contract. The user-facing guide lives under UI widgets.


๐Ÿ“ฆ Widget definition

A .widget file and the API object share the same shape:

{
  "uuid": "โ€ฆ",
  "name": "Order status",
  "description": "Shows the status of an order",
  "category": "ecommerce",
  "tree": { "type": "Card", "children": [] },
  "schema": { "type": "object", "properties": {} },
  "defaultState": {},
  "examples": [{ "name": "Example 1", "state": {} }],
  "states": [],
  "functions": []
}
  • category: booking | ecommerce | forms | analytics | other.
  • tree โ€” a single root node; the JSX view is printed from it.
  • schema โ€” a JSON Schema subset: type, properties, items, required, enum, default, format, description.

๐ŸŒฒ The node tree

Every node is an object with a type; children live in children:

{
  "type": "Card",
  "gap": 3,
  "children": [
    { "type": "Title", "value": "{{order.title}}", "size": "lg" },
    { "type": "Badge", "label": "{{order.status}}", "color": "info" },
    {
      "type": "Repeat",
      "each": "{{order.items}}",
      "as": "item",
      "children": [{ "type": "Text", "value": "{{item.name}}" }]
    }
  ]
}
  • A binding is a path in double curly braces. A prop that is exactly one binding keeps the bound value's type.
  • Repeat iterates an array (each, as); the item index is exposed as <as>Index.
  • State links to a visibility rule by name.

โš™๏ธ Function objects

{ "name": "confirm", "type": "call_api",
  "url": "https://api.example.com/book",
  "method": "POST",
  "headers": { "Authorization": "Bearer โ€ฆ" },
  "inputs": { "id": "{{order.id}}", "note": "{{note}}" },
  "additionalInputs": ["note"],
  "onSuccess": { "type": "set_variables", "variables": { "booked": true } },
  "onFailure": { "type": "set_variables", "variables": { "error": "โ€ฆ" } } }

Other types: set_variables (variables), send_message (message, hidden), open_link (url), dismiss.

๐Ÿ” How call_api is executed

  • When a widget is delivered into a conversation, a call_api function loses its url, method, headers and inputs, and is marked as proxied.
  • The browser sends only the function name and the inputs; the server performs the request against your endpoint.
  • The server resolves tokens against the state stored with the message, overlaid with the accepted inputs.
  • inputs is a whitelist: keys not declared in the function's additionalInputs are dropped.

๐ŸŒ The visitor-side call

POST /api/v1/widget/ui-widget/{widget_uuid}/functions/execute

{
  "message_uuid": "โ€ฆ",
  "function_name": "confirm",
  "inputs": { "note": "hi" },
  "tool_call_id": "call_1"
}
  • Authorized with the chat widget's own token.
  • message_uuid is required: it proves the visitor was shown this widget. State and session are read server-side and never accepted from the browser.
  • tool_call_id disambiguates a message that rendered the same widget twice.

๐Ÿšจ Errors

{ "success": false, "error": { "code": "โ€ฆ", "message": "โ€ฆ" } }
  • WIDGET_FUNCTION_NOT_CALLABLE โ€” the visitor may not call this function.
  • WIDGET_INVALID_TOKEN, NOT_A_WIDGET_VISITOR โ€” token problems.
  • WIDGET_NOT_IN_MESSAGE โ€” no message rendered this widget.
  • WIDGET_FUNCTION_NOT_FOUND, WIDGET_FUNCTION_FAILED, WIDGET_FUNCTION_UNAVAILABLE.
  • 429 โ€” rate limit (60 requests per minute per IP).
  • A 200 with ok: false means your own API refused the request.

๐Ÿ“ค What your endpoint should return

  • A JSON object. With waitForResponse the response is merged into the widget data and bindings re-render.
  • Return the field names from the schema, or use the Call API + show widget action with a response mapping: { "orders": "data.items" }.
  • There is no idempotency key โ€” guard repeated calls on your side. The browser blocks a parallel call of the same function, but network retries are still possible.

๐Ÿงพ Limits

  • Only whitelisted components may appear in the tree; anything else is rejected.
  • Widgets are project-scoped: a widget from another project is not found.
  • The Map component and the iframe-based client function are not supported yet.