Skip to main content

Embed Triggers

An embed trigger builds an element you paste onto your own site. A visitor uses it, and your flow runs. There are three, and they are chosen when you add the node:
The Add Node panel offers Chat and Embed separately. Chat is a shortcut that pre-selects the chat type; Embed asks you which of the three you want. They produce the same kind of node.

What you actually paste

Two lines of HTML: a script tag that defines a custom element, and the element itself. There is no JavaScript SDK, no initialiser and no callbacks to register.
The tag and script differ per type: Both lines are generated for you, filled in, with a copy button on each. Take them from the node’s Embed Code tab rather than typing them — collection_topic, flow_topic and node_topic all come from your flow’s own identifiers.
Copy the snippet again after you change the node’s ID or switch the embed type. The editor flags both cases, but an embed already live on your site keeps pointing at the old one and quietly stops working.

Setting one up

1

Add the trigger and pick a type

Button, Form or Chat.
2

Design it under Settings

Fields, text, colours and behaviour. Covered per type below.
3

Generate an API key

Embed Code → API Key, set Expiry (days) (365 by default), press Generate API Key.
4

Add your site under Allowed Hosts

Nothing loads in a browser until the origin is on the list.
5

Copy the two lines from Embedding

Paste them into your page.
The API key comes first. The Embed Code tab shows only the API Key panel until a key exists — the embedding snippet, Context and Allowed Hosts panels are not there before that. The panel says as much: “To embed this element, you need to generate an API key first.”
There is no regenerate. Remove API Key deletes it; generating again issues a new one, and any page still carrying the old key stops working.

What the flow receives

This is the part that differs most between the three, and it decides how you write every later step.

Form

$.trigger is a flat object keyed by each field’s property key — derived from the field’s label in camel case unless you set it yourself — plus a context key. A form with fields labelled Full name, Work email and Team size delivers:
There is no form wrapper. $.trigger.form.email resolves to nothing — the fields sit directly under $.trigger.

Button

A standalone button sends only the context object. A button used as a form’s submit control sends the form’s values, as above.

Chat

$.trigger is the visitor’s message as a plain string, not an object.
There are no sub-paths. Files a visitor attaches are delivered to the run as knowledge, so an Assistant step can read them; other step types cannot see them.
What runs after the trigger is decided by each step’s outcome, not by the arrows in the editor. A Condition step’s outcome names the step IDs to run next — one, several (they start at the same time), or the reserved RESOLVE_SUCCESS / RESOLVE_ERROR to end the run. A line drawn between two steps that no outcome names is decoration.

The Button

Under Settings:
  • Display Mode — Quiva uses the platform’s own button; Native renders a plain <button> you style yourself.
  • Text and Tooltip.
  • Color and Size — named values from a fixed palette, shown only in Quiva mode.
  • Attributes — an id and CSS classes, so your own stylesheet can reach the element.
  • Event Behavior — preventDefault and stopPropagation, for a button that sits inside your own form.
  • Theme — light and dark theme builders, plus raw CSS.

Trigger Event and the URL it calls

Trigger Event offers HTTP Request and Open Flow Chat.
Only HTTP Request does anything. Selecting Open Flow Chat still sends an HTTP request — there is no chat-opening behaviour behind it. Use a Chat embed for a chat widget.
The button posts to an HTTP Request trigger on your gateway. Trigger URL starts as “Default Trigger URL”, which is not a working endpoint:
Press Custom Trigger and create the endpoint. A button with no trigger of its own has nowhere to post and will fail on every press. This is a required step, not an option.
Once created, Trigger Params exposes Public URL, Timeout and Requests / Second for that endpoint. They behave exactly as described on the HTTP Request trigger page.

The Form

The form editor is a grid builder, not a field list.
1

Add Row

Choose a grid template — one, two, three or four columns with fixed proportions.
2

Click a cell

Pick the field type and configure it.
There is no drag-and-drop rearranging. The Layout panel has a single control, Grid gap.

Field types

Text Input, Textarea, Email, Number, Select, Multi Select, Toggle, Multi Toggle, Checkbox, Currency, Phone, Country, Multi Country, Date, Date Range.
There is no radio-button field and no file-upload field. A single-choice question is a Select or a Multi Toggle; a form cannot take a file.

Validation

Each field has a Validation panel offering required, email, min and max, each with its own message. Which of the four appear depends on the field type.
There is no pattern or regular-expression rule and no custom validator hook. Anything beyond required / email / min / max has to be checked in the flow, after submission.

After submission

The form shows an inline success message and stays where it is. There is no redirect, no reset-or-keep choice and no configurable success text.

The Chat

Under Settings, grouped into panels:
There is no auto-open delay, no sound or desktop notification, no session-duration setting and no quick-reply list. Raw CSS is not available for the chat widget. Markdown in replies is always rendered — there is nothing to switch.

Context — collecting data from the host page

Embed Code → Context appears when advanced mode is on. It defines named values read from the visitor’s browser when the embed loads, and delivered to the flow under $.trigger.context. Available sources: localStorage (by key), document.cookie (by name), document.title, a query-string parameter, location.href / pathname / host / protocol / search / hash / origin, and navigator.userAgent / language / onLine / platform. Give each entry a name and pick its source; the flow then reads it at $.trigger.context.<name>. It is the only way to know which page an embed was used on, or to carry a campaign parameter through.
Values are read on the visitor’s device and sent with the submission. Cookies and localStorage entries are readable this way, so name only what you intend to collect and what you have told visitors you collect.

Allowed Hosts

A browser will not load an embed from an origin that is not on the list. Add every host your page is served from, including the www variant if you use one.
This list belongs to your account’s gateway, not to the embed. Every embed and every API consumer on that gateway shares it — two embeds cannot have different allowlists.

Security

The embed’s API key is published in your page’s HTML, where anyone can read it. It is deliberately narrow: it may run this one flow, read this node’s configuration, and manage its own chat sessions. It cannot do anything else on your account. That still leaves it usable by anyone who copies it, from any origin on your allowlist. Assume any embed can be driven with arbitrary input, and validate in the flow rather than in the element:
  • Check $.trigger values in a Condition step before doing work that costs money or writes data.
  • Keep Allowed Hosts as narrow as you can.
  • Rotate by removing the key and generating a new one, then re-copying the snippet.

Draft and published flows

The embed’s key is granted on both the draft and the published flow, so the snippet keeps working across a publish and does not need re-copying. Which one actually runs follows the flow subject baked into the snippet — copy the code from the published flow when you go live.

Troubleshooting

Expected. Generate a key and the other panels appear.
Check the browser console for a CORS refusal, then add the origin under Allowed Hosts. Confirm both lines were pasted — the script tag alone does nothing.
It has no endpoint. Open the button’s Trigger URL row; if it reads “Default Trigger URL”, press Custom Trigger and create one.
The node ID changed, the embed type changed, or the API key was removed and regenerated. Any of the three invalidates a snippet already on your site — re-copy it.
Read $.trigger.<propertyKey>, not $.trigger.form.<field>. The property key is the field’s label in camel case unless you set one.
For chat it is a plain string. Use $.trigger on its own.
That option has no behaviour behind it. Add a Chat embed instead.

Next Steps

HTTP Request Trigger

The endpoint a button or form posts to

Assistant Step

Answering a chat message

Condition Step

Validating a submission before acting on it

Triggers Overview

Every way a flow can start