Chat widget
The widget is a small loader script plus an iframe app. Your widget inbox’s settings page shows the exact snippet with your key filled in:
<script> window.SteptSettings = { workspaceKey: "wk_…", // your widget inbox key apiBase: "https://app.stepped.ai", // optional; defaults to the loader script's origin // identify logged-in users (HMAC-verified — see below): // identity: { external_id: "user-123", email: "[email protected]", name: "Ada", hash: "…" }, // extra origins the AI assistant may navigate to (own origin always allowed): // aiAllowedOrigins: [], }</script><script src="https://app.stepped.ai/widget-assets/loader.js" async></script>Command API
Section titled “Command API”The loader installs a global Stept(...) function with an Intercom-style pre-load queue
(calls made before the script loads are replayed):
Stept('open') // open the messengerStept('close') // close itStept('toggle')Stept('show') // show / hide the launcherStept('hide')Stept('shutdown') // tear the widget down (e.g. on logout)Stept('startTour', id) // play a published tour by idIdentity verification
Section titled “Identity verification”Anonymous visitors get a generated visitor id. For logged-in users, pass identity with an
HMAC so nobody can impersonate another user:
hash = HMAC-SHA256(identity_secret, external_id) // hex, computed on YOUR serverFetch the workspace’s identity_secret once with
GET /api/v1/w/{workspace_id}/identity-secret (requires the workspace:manage
permission) and keep it server-side. Verified contacts are flagged hmac_verified. Set
require_identity in the widget inbox config to refuse anonymous visitors entirely.
How conversations are created
Section titled “How conversations are created”- The widget calls
POST /api/widget/bootwith the widget key (+ identity if provided) and receives a scoped widget token. All further calls send it asX-Widget-Token. - Sending the first message calls
POST /api/widget/conversations— this reuses the contact’s latest non-resolved conversation on that inbox, or creates a new one. - Replies, read receipts and typing indicators go through
/api/widget/conversations/{id}/…; the widget listens for realtime updates over a WebSocket (/ws/widget?token=…), so agent replies appear instantly.
If the inbox has published help-center articles, the widget also shows a Help tab (see Help center).
The in-app AI assistant (page control)
Section titled “The in-app AI assistant (page control)”When the inbox’s AI agent has page control enabled, the agent can see and operate the page the visitor is on — the tools run in the host page DOM, brokered through the widget.
Consent model, in increasing order:
page_control.enabledon the agent — unlocks read-only tools:page_snapshot,page_find,page_read,page_scroll,page_wait, plus the guide toolsshow_guide(plays a published tour) andshow_steps(an ad-hoc walkthrough, max 8 steps).page_control.allow_actionson the agent and the visitor ticking the consent checkbox in the messenger — only then do the mutating toolspage_act(click/type) andpage_navigateexist. Consent is stored per conversation; tools the agent isn’t entitled to are never offered to the model at all.
Hard limits, regardless of consent:
- Password fields are never typed into or read.
- Navigation is same-origin only, unless you allowlist origins via
aiAllowedOrigins. - Mark any element
data-stept-no-aito make it invisible and untouchable to the agent. - At most 12 mutating operations per agent run.
- The widget’s own UI is invisible to the agent.
Each operation round-trips through the backend (the run pauses as awaiting_client, the
widget executes, posts the result back, the run resumes) — so every page action appears in
the run’s step trace like any other tool call.