Skip to content

Widget parameters

Every option works two ways: as a query parameter on the widget.js URL, or as a data-<name> attribute on the script tag. Query parameters win when both are present, and they survive tag managers that strip attributes.

OptionValuesDoes
agentembed nameRequired. Which agent answers. Any name the agent has ever had resolves to it, so renaming never breaks a live tag.
positionleft, rightWhich corner the launcher sits in. Overrides the agent setting.
langlanguage codePins the interface language instead of following the visitor.
offset-bottompixelsMoves the launcher up, clear of something else.
offset-sidepixelsMoves the launcher in from its edge.
qtextPre-fills the input. Never sent automatically.
pageURLThe page to attribute the conversation to. For iframes.
modeembed, fullpageSet by the hosted chat page; not normally used by hand.
apioriginOverrides where API calls go. Defaults to wherever widget.js was served from.
<script src="https://engadin.ai/widget.js?agent=acme&position=left&offset-bottom=90" defer></script>

Read live from the page, so they can change with your own state and the launcher animates between positions:

PropertyDoes
--eng-offset-bottomDistance from the bottom edge.
--eng-offset-sideDistance from the left or right edge.
body:has(.to-top-button.is-visible) { --eng-offset-bottom: 96px; }
AttributeDoes
data-engadin-openClicking the element opens the chat.
data-engadin-open="<question>"Opens it with that question pre-filled.

A ?engadin_q=<question> parameter on any page URL does the same thing, which lets a plain link from elsewhere on your site open the chat with a question ready.

CallDoes
window.engadin.open()Opens the chat.
window.engadin.open('<question>')Opens it and types that question into the input.
window.engadin.open({ prefill: '<question>' })The same, object form.
window.engadin.close()Closes the panel. No effect on the full-page chat.

Pre-filled text is never sent: the visitor still presses send. Input is whitespace-collapsed and capped at 600 characters. Calls made before the widget has finished booting are queued rather than dropped.

For an iframe embed, the host page reaches the same behaviour with a message to the frame:

frame.contentWindow.postMessage(
{ type: 'engadin-prefill', prefill: 'Do you ship to Switzerland?' },
'https://engadin.ai'
);

See suggesting a question from JavaScript for worked examples.

https://engadin.ai/chat

ParameterDoes
agentWhich agent. Required on the platform’s domain; a workspace’s own domain falls back to its first agent.
embed1 renders the compact variant, without the sidebar. For iframes.
langPins the language.
pageThe real page an iframe sits on, for attribution.
qPre-fills the input.
<iframe src="https://engadin.ai/chat?agent=acme&embed=1&page=https%3A%2F%2Fexample.com%2Fpricing"
style="width:100%;height:640px;border:none"
allow="microphone"></iframe>

Every event goes out three ways at once: pushed to window.dataLayer as engadin_<name>, dispatched on window as an engadin CustomEvent, and posted to the parent window from inside an iframe.

window.addEventListener('engadin', (e) => {
e.detail; // { event: 'message_rated', agent: 'your-agent', rating: 'up' }
});

Every payload has event and agent. Some carry one extra field:

EventExtraWhen
widget_loadedThe script booted and the launcher exists.
chat_openedvia: launcher, teaser, auto, deeplink, apiThe panel opened. Fires on every open.
chat_closedThe panel closed.
chat_restoredA returning visitor’s conversation was reloaded.
conversation_startedThe first message of a new conversation.
conversation_started_suggestedThat first message came from a suggested question, and fires alongside the previous one.
suggested_question_clickedA suggestion chip was clicked.
message_sentAny message the visitor sent.
voice_message_sentThat message came from voice, and fires alongside message_sent.
message_ratedrating: up, downThumb pressed on an answer.
rating_reasonreason: wrong, incomplete, outdatedA reason chosen after a thumb down.
lead_createdA conversation produced a new lead.
lead_updatedAn existing lead gained details.
link_clickedurlA link inside the conversation was clicked.
attachment_uploadedA visitor attached a file.
ticket_offer_shownThe assistant offered to open a ticket.
ticket_createdThe visitor took it.
chat_downloadedThe visitor saved the conversation as a text file.
chat_emailedThe visitor had the conversation mailed to an address they typed.
action_runaction: slugA custom action started mid-reply.
action_okaction: slugIt succeeded.
action_failedaction: slugIt failed or timed out.
teaser_shownA proactive teaser bubble appeared.
teaser_dismissedThe visitor dismissed it.
voice_chat_openedVoice mode was opened.
error_shownThe visitor saw an error message.

Never any message content, and nothing a visitor typed. link_clicked carries the destination URL only.

For iframe embeds, add the bridge script next to the frame so the same events reach the host page:

<script src="https://engadin.ai/widget-events.js" defer></script>

On a custom domain, widget.js, widget-events.js, /chat and the API all answer on your own hostname as well. Use it in all of them, so every request stays first-party.

See analytics events for the Google Tag Manager setup.

URLWhat
/api/healthLiveness plus the active model provider.
/help/microphoneVisitor-facing help for a blocked microphone. ?lang=de for German.