Skip to content

Embedding

Embed your Ragtime assistant into any website or application using a simple iframe. Pass data via query parameters or POST body, and optionally secure requests with HMAC signatures.

The simplest way to embed your assistant is a standard iframe. Replace the URL with your assistant’s live URL (found in Dashboard → Assistant → Deployment):

<iframe
src="https://your-ragtime-instance.com/chat/org-slug/assistant-slug"
width="100%"
height="700"
style="border: none; border-radius: 12px;"
allow="microphone"
></iframe>

If you’ve configured External Variables (Dashboard → Assistant → Deployment → External Variables) with URL Query source, append them as query parameters:

<!-- Pass data via URL query parameters -->
<iframe
src="https://your-ragtime-instance.com/chat/org-slug/assistant-slug?user_name=John&locale=en"
width="100%"
height="700"
style="border: none; border-radius: 12px;"
allow="microphone"
name="ragtime-chat"
></iframe>

For sensitive data, use POST Body variables. Create a hidden form that targets the iframe by name:

<!-- When using POST body parameters, submit via a form targeting the iframe -->
<iframe
name="ragtime-chat"
width="100%"
height="700"
style="border: none; border-radius: 12px;"
allow="microphone"
></iframe>
<form
method="POST"
action="https://your-ragtime-instance.com/chat/org-slug/assistant-slug"
target="ragtime-chat"
style="display:none;"
>
<input type="hidden" name="user_id" value="abc123" />
<input type="hidden" name="session_token" value="..." />
</form>

When Security is enabled in Deployment settings, all requests must include a valid HMAC-SHA256 signature. This means you cannot use a static HTML snippet — signature and timestamp must be generated on your server:

import crypto from 'crypto';
/**
* Generate an HMAC-SHA256 signature for request verification.
* The signing secret is found in Dashboard → Assistant → Deployment → Security.
*/
function generateHmacSignature(secret: string, payload: string): string {
return crypto.createHmac('sha256', secret).update(payload).digest('hex');
}
async function generateSignedUrl() {
const baseUrl = 'https://your-ragtime-instance.com/chat/org-slug/assistant-slug';
const params = new URLSearchParams();
// Add any query parameters
params.append('user_name', 'John');
// Generate signature
const timestamp = Date.now().toString();
params.append('timestamp', timestamp);
params.sort();
const payload = params.toString();
const signature = generateHmacSignature(process.env.RAGTIME_SIGNING_SECRET!, payload);
params.append('signature', signature);
return `${baseUrl}?${params.toString()}`;
}

The signing secret is found in Dashboard → Assistant → Deployment → Security. Keep it server-side — never expose it to the client.

The embedded assistant communicates with your page via postMessage. Add this listener to capture lifecycle events and AI-triggered actions:

// Listen for Ragtime chat events and actions
window.addEventListener('message', (event) => {
const { data } = event;
// Lifecycle events:
// chat_started, thinking, response_start, response_given, emotion,
// session_ended_idle, session_ended_natural, session_restarted, listening,
// session_ended_user, session_ended_remote, session_ended_max_duration, session_ended_error,
// idle_timeout_start, idle_timeout_tick, idle_timeout_stop,
// mic_timeout_start, mic_timeout_tick, mic_timeout_stop, mic_max_duration
//
// Transcript events (opt-in via Deployment settings):
// transcript_user, transcript_assistant
if (data?.type === 'ragtime-event') {
console.log('[Ragtime Event]', data.event, data.detail);
}
// AI-triggered client actions (configured in the Actions tab)
if (data?.type === 'ragtime-action') {
console.log('[Ragtime Action]', data.action, data.args);
}
});
CategoryEvents
Chat lifecyclechat_started, thinking, response_start, response_given, emotion
Session endsession_ended_idle, session_ended_natural, session_ended_user, session_ended_remote, session_ended_max_duration, session_ended_error
Session controlsession_restarted, listening
Idle timeoutidle_timeout_start, idle_timeout_tick, idle_timeout_stop
Mic timeoutmic_timeout_start, mic_timeout_tick, mic_timeout_stop, mic_max_duration
Transcript (opt-in)transcript_user, transcript_assistant

For a quick start, use the Starter Page download button in Dashboard → Assistant → Deployment. It generates a ready-to-open HTML file with your assistant embedded and an event log — perfect for testing your integration locally.

Customers can ship a fully custom HTML “shell” around the chat (header, branding, per-device JS, etc.) and have Ragtime serve it as a real page. Configure it in Dashboard → Deployment → Custom template and toggle individual devices to use the template under Devices. Once a template is published, the device’s public URL switches from /chat/<org>/<project>/<device> to /embed/<org>/<project>/<device>.

Everything above on this page works identically — just swap the URL. Query parameters, POST body variables, HMAC signatures, and the postMessage event stream are all forwarded between the outer /embed/... page and the chat iframe it wraps, so an external host that iframes /embed/... sees the same protocol as one that iframes /chat/... directly.

Inside the template itself, customer JS gets two extra conveniences:

  • window.addEventListener('ragtime:event', e => …) — chat events re-dispatched as DOM CustomEvents.
  • window.ragtime.send(type, detail) — post a message into the chat iframe.

The {{RAGTIME_IFRAME}} token in the template is replaced with the chat iframe at render time. Two extra tokens are substituted per-request so a single template can branch on which device is hosting it:

  • {{DEVICE_SLUG}} — URL-safe device identifier (e.g. kiosk-a). HTML-escaped; safe to use as text content or inside double-quoted attribute values.
  • {{DEVICE_NAME}} — human-readable device label, HTML-escaped under the same rules.

On the preview route (/embed/<projectId>) both tokens resolve to preview / Preview since the preview isn’t bound to a specific device.

External Variables (declared under Deployment → Embedding → External Variables) work the same way for /embed/... as they do for /chat/... — values arrive via query string or POST body and are injected into the system prompt only if the variable is declared in the dashboard.