Skip to content

Embed a widget on your site

You can put the product on your own website with a <script> tag. There are two widgets, and which one you want depends on whether visitors should have a conversation or run one specific thing.

Chat widget Workflow widget
What a visitor gets A conversation with an assistant One workflow, with its inputs
Interactive forms Yes No — it displays results only
Script chat-widget.js workflow-widget.js

Both are self-contained: no framework on your page, no stylesheet to include, and nothing to build.

<script src="https://app.example.com/chat-widget.js"></script>
<script>
sapajaChat('init', {
templateId: 'your-template-id',
token: 'your-embed-token',
});
</script>

You get the template id and its token from the workspace that owns the chat template. The token is what authorises the widget, and it is tied to a list of sites that may use it — a token used from a domain that is not on that list is refused, so a copied token does not work elsewhere.

Replies are not plain text. The widget renders the same rich surfaces the in-app chat does — cards, tables, statistics, badges, charts and images — so a result arrives as something readable rather than a blob of JSON.

The chat widget also renders real forms. When the assistant needs details before it can run something, the visitor gets labelled fields and a submit button instead of being asked to type values into a sentence. A few behaviours worth knowing:

  • An incomplete submit comes back as a corrected form, with the missing fields marked, rather than an error.
  • If a submit cannot reach us, the form stays editable and offers a retry — it never falsely reports success.
  • A submitted form stays visible but frozen, marked as submitted, so the visitor can see what they sent.

The workflow widget displays results but has no forms; it collects what it needs up front.

The widget speaks the visitor’s language, not yours. It works out which to use in this order: the language you configure, then the visitor’s browser, then English.

sapajaChat('init', { templateId: '', token: '', locale: 'fr' });

Supported: en, fr, es, th, zh and zh-HK. Ordinary browser tags are fine — fr-CA becomes French, zh-TW becomes Traditional Chinese. Anything unrecognised falls back to English rather than failing.

This covers the widget’s own controls and everything the assistant generates: status lines, completion messages, result-card labels and the replies themselves. It applies per message, so a visitor who switches language mid-conversation gets the new one from their next message. Content already sent is never retranslated — a result card stays in the language it was built in.

If a conversation starts a long-running job, the language travels with it, so the completion message arrives in the language the visitor was using even if that is hours later.

One exception: text written by whoever built the workflow — field descriptions, clarification prompts and custom displays — appears as they wrote it. That is authored content rather than product copy, so it is not translated.

You do not have to use the widgets. The embed endpoints are documented in the REST API reference, and they take the same locale value on each call — send it and you get the same behaviour, omit it and you get English.

  • No microphone button. Voice needs a secure connection. On a page served over plain HTTP the browser will not grant microphone access at all, so the control is not shown. Serve your page over HTTPS.
  • A component does not render. The widget only renders known component types and silently drops anything else, so a display it cannot understand is skipped rather than shown broken.
  • The widget stops working. If the workspace that owns the embed no longer has an active subscription, the widget declines politely rather than showing your visitors a billing message.