The Scripts page is where you get the embed snippet and the widget key
that lets a website talk to your published flows. A widget key is the public
credential the embed <script> references so the widget can load this tenant’s
published flows as actions the visitor can run.
Menu: Scripts (/admin/scripts, route admin_scripts_index,
perm comerix.scripts.view).
Permissions
Grant these ACL leaves per role under Access → Roles:
| Resource | Grants |
|---|
comerix.scripts.view | View the Scripts page — pick a public key and copy the embed snippet. |
Issuing and managing the keys themselves lives on the
Public keys page, gated by comerix.public_keys.view /
comerix.public_keys.manage.
The Scripts page
/admin/scripts (perm comerix.scripts.view) shows two things:
- A public-key selector — pick which of the workspace’s public keys the
embed snippet should carry. No keys yet? The page shows Add a public key,
which takes you to Public keys to issue one.
- The copy-paste embed
<script> snippet for your site, carrying the selected
key in data-public-key.
Paste the snippet into the pages where the chat widget should appear. The key it
carries is what loads this tenant’s published flows into the widget.
Issuing & managing keys
Keys are issued and managed on the Public keys page — issue,
rotate, pause/resume, revoke, and scope a key’s allowed origins and mounts. The
Scripts page only selects which existing key the snippet carries; the Manage
public keys link takes you straight there.
A widget key is a public credential of the form pk_live_…. It is safe to
embed in client-side JavaScript — its protection is its allowed origins list
plus browser CORS, so a script on an unrelated site can’t use it.
Each key grants access to one or more intents. An intent is the handle a
published flow registers under; one intent maps to one published flow. So a key
effectively decides which of your published flows a given site may run.
For the precise vocabulary — widget key, intent, session, conversation — see
Concepts.
Advanced & CLI
Most options — environment, allowed origins, mount scope, and rotation — are set
on the Public keys page. For scripting or CI, the
comerix:api-key:create console command issues a key with an explicit intent
allow-list (versus all-intents), allowed origins, and an optional webhook URL
plus secret:
php bin/console comerix:api-key:create
See Scenario and Lifecycle for the command
reference and an end-to-end integration walkthrough.
Quick questions
Quick questions are one-tap prompts the widget offers a first-time visitor
when they open the chat — a shortcut into a flow without the visitor having to
type anything. You can configure up to six.
Each prompt is one row with three fields:
| Field | What it does |
|---|
| Question | The text shown on the chip the visitor taps. |
| Page type | Which kind of page the prompt is meant for, so the widget can show the right prompts in context. One of General, Category, Product, or Cart. |
| Assigned flow | The published flow that runs when the visitor taps the prompt. Picked from a live dropdown of this workspace’s flows; choose None to leave it unassigned. |
Quick questions live under Settings → Widget → Quick Questions
(/admin/config/widget, route admin_config_section). They are edited with the
rows editor — click Add to create a row, fill in the three fields, and
reorder or remove rows as needed. The list is capped at six rows.
Because each prompt binds to a specific page and flow, this setting is editable
only at workspace (tenant) scope — you cannot set it at the global or
organization level.
How they reach the visitor
When the host page opens a session, the response carries a quickQuestions
array alongside the intents list, and the widget renders the chips from it:
{
"sessionToken": "…",
"conversationId": "…",
"intents": [ … ],
"quickQuestions": [
{
"question": "Where is my order?",
"pageType": "general",
"flowId": "…",
"intentName": "order_status"
}
]
}
The widget posts intentName back to /api/public/v1/chat/messages to start
the flow, exactly as it would for any intent.
A prompt whose assigned flow is unset, not yet published, or not
permitted by the widget key’s intent allow-list comes back with
intentName: null. The client can still show it (greyed out) but cannot
start a flow from it. Always assign a published flow that the key is allowed
to trigger.
Page filtering is left to the host page — only it knows which page the visitor
is on, so it decides which pageType prompts to surface.
The host page can also fetch the prompts without opening a session: the
anonymous, cacheable GET /api/public/v1/chat/quick-questions endpoint serves
the same rows (optionally narrowed with ?pageTypes=general,category), and the
widget’s publicly readable appearance values are served by
GET /api/public/v1/config/widget. See the
Public read API.
Conversation variables
When the host page opens a session it can pass a top-level variables map —
a JSON object of key/value pairs about the visitor or the page (for example a
plan name, a cart total, or the current product id). Those values are stored on
the conversation and are readable inside your flows as variables, which makes
them handy for personalizing replies.
{
"publicKey": "pk_live_…",
"variables": {
"plan": "pro",
"cart_total": 129.0
}
}
Variable keys must be snake_case (1–64 chars, [a-z0-9_], leading letter).
The whole map is bounded — at most 50 keys, 4 KB serialized, and nesting
4 levels deep; values may be scalars, null, or nested arrays. The same
variables map may also be sent with each message to add or update values
mid-conversation.
Variables come from the public, unauthenticated widget endpoint, so treat
them as untrusted input in your flows — never trust a value to be
accurate or safe without validating it.
For the full request/response shapes and where variables fit in the session
lifecycle, see Lifecycle and the
OpenAPI spec.
Where to go next