Embedding on a Website
Once the assistant is published and you have at least one channel, there are several ways to put it on a site. They range from copy-paste simple to fully server-signed.
Simple iframe (most common)
Section titled “Simple iframe (most common)”Select a target channel on the Embedding tab and copy the snippet:
<iframe src="https://<host>/chat/<orgSlug>/<projectSlug>/<deviceSlug>" width="100%" height="600px" frameborder="0" allow="microphone; camera; display-capture; autoplay"></iframe>The allow attributes let voice and avatar modes access the mic and camera.
Passing data in: External Variables
Section titled “Passing data in: External Variables”If your page needs to tell the assistant something (a visitor’s name, a product ID, a course code), declare External Variables on the Embedding tab. Each variable has a source:
| Source | How it’s sent | Good for |
|---|---|---|
| URL Query | Appended to the iframe src (?user_name=VALUE) |
Non-sensitive data |
| POST Body | Submitted via a small form that targets the iframe | Data you don’t want in a URL |
The Embedding tab generates the matching snippet (iframe or form + iframe) for the variables you’ve declared. Each variable also has a type (text up to 200 characters, number, yes/no, choice list or ID); a value that does not fit is dropped. See Variable types.
Anyone who can send a visitor a link can set URL and form values, unless request signing is on (below).
Preselecting chat language with ?lang=
Section titled “Preselecting chat language with ?lang=”You can preselect the session language by adding a lang query parameter to
the chat URL:
https://<host>/chat/<orgSlug>/<projectSlug>/<deviceSlug>?lang=nlRagtime applies this exactly like a user language pick in the UI.
When it applies
Section titled “When it applies”- If Chat Languages has an explicit selected list,
?lang=must match one of those selected language codes. - If All Languages is enabled, any known Ragtime language code is accepted.
- Invalid or unknown codes are ignored (with an info-level browser console log).
Precedence with pre-experience
Section titled “Precedence with pre-experience”If pre-experience shows a manual language selector (for example, multiple
explicitly selected languages), manual user choice takes precedence and
?lang= is ignored.
If pre-experience is enabled but no language selector is shown (single-language
or no-manual-choice flow), ?lang= still applies.
Which links support this
Section titled “Which links support this”?lang= works on all deployment routes that resolve into the chat runtime:
/chat/<projectId>(internal preview)/chat/<orgSlug>/<projectSlug>/<deviceSlug>(published device links)/i/<token>(recipient links)/embed/...routes (the embed shell forwards query params to the inner chat URL)
HMAC-signed embeds (secure)
Section titled “HMAC-signed embeds (secure)”Enable Security → Require signature so Ragtime only accepts values your server signed. When on, every chat link that carries values (external variables or injection), every form POST to the chat page, and every direct API call must be signed with your Signing Secret. A plain link without values needs no signature. Signatures are valid for 5 minutes; an unsigned or expired one gets a 401 Invalid signature.
Trade-off: you can no longer use a static HTML snippet. The signed URL must be generated server-side on each load. The Embedding tab shows the signed-URL pattern and reminds you of this. Details: HMAC Signature.
Restrict who may embed: Allowed Domains
Section titled “Restrict who may embed: Allowed Domains”Add the domains that are permitted to iframe the assistant (subdomains are
included automatically). With the list empty, the assistant cannot be embedded
anywhere; opening the link directly still works. This is enforced with
frame-ancestors on the chat page and the custom-template shell, and with CORS
on the API.
A site that is not listed sees a short message in the frame naming itself and this setting, so the fix is clear. (If the browser does not say which site is embedding, it blocks the frame on its own.) An LMS must be listed too, including the domain it serves content from, such as a separate SCORM sandbox domain.
Download packages
Section titled “Download packages”Deployment → Embedding → Download Packages gives you two ready-made bundles:
Starter Page
Section titled “Starter Page”A standalone HTML file with the embedded chat plus a live event log — open it
in any browser and watch the postMessage event stream. If HMAC signing or
domain restrictions are enabled, you’ll need to host it behind a small backend.
SCORM package
Section titled “SCORM package”A zipped SCORM 1.2 or 2004 package to upload directly into an LMS. Add the domain your LMS serves SCORM content from to Allowed Domains first, or the assistant will not load inside it. The assistant runs inside the LMS player and reports completion via the SCORM API:
| Ragtime event | SCORM status |
|---|---|
| Chat started | incomplete |
| Session ended naturally / by user | completed |
| Session ended by idle / max duration | completed |
| Session ended by error | incomplete |
| Window closed mid-session | Time committed, status unchanged |
For modern LMS delivery with seat licensing, prefer LTI over SCORM.
Listening to the conversation from your page
Section titled “Listening to the conversation from your page”The embed emits a postMessage event stream your page can react to:
chat_started, thinking, response_start, response_given, emotion,
stage_changed,
action events, and — if you opt in under Additional Permissions → Transcript
Events — transcript_user / transcript_assistant with the full
conversation text.
Your page can also tell a running chat what the visitor is doing, with Page events, declared under Actions → Page events. And with Injection enabled, it can override instructions or pre-populate the chat at load time. Injection needs request signing on, and is only accepted on signed requests. See the Chat Injection docs for details.
If your host application controls a staged flow backed by conversation stages, you can switch stages directly from the host page:
frame.contentWindow.postMessage( { type: 'ragtime-host', action: 'set-stage', stageId: 'stage-3' }, 'https://<host>');Use stage_changed as the confirmation signal for the stage that was
actually applied.