Widget and SDK Setup

Use the widget when you want Kravos.ai to own the customer chat surface: launcher button, iframe, session setup,

Widget and SDK Setup

Use the widget when you want Kravos.ai to own the customer chat surface: launcher button, iframe, session setup, pre-chat collection, voice handoff, end-chat feedback, and conversation history. Use the SDK and dashboard-domain SDK routes when you need to embed that same surface inside your product or build a thin custom wrapper around it.

Dashboard-domain, not public API v1

Widget routes live on your Kravos web app domain, for example https://app.kravos.ai/widget, /sdk/v1/loader.js, /api/sdk/*, and /api/chat/stream. The server-to-server public API lives at https://api.kravos.ai/v1. Do not move widget calls to the public API host unless the endpoint is explicitly listed in API Reference.

Quickstart

Create an agent-scoped chat key

Open the agent's API keys page and create a key with the chat permission. The widget chooses its agent from this key. There is no public agentId query parameter.

Configure the widget in the dashboard

Use Widget Settings to set colors, greeting text, pre-chat fields, voice, and embed surface.

Install on a staging page

Start with the script snippet from the Embed tab. Test the real page, not only the dashboard preview, because placement and domain allowlists are page-dependent.

Check the first conversations

After launch, review Conversations, Feedbacks, and Analytics for early traffic and answer quality.

Install Options

Script loader

The dashboard embed tab generates this option. It injects the iframe, adds a floating launcher button, validates messages from the iframe origin, and starts minimized.

<script src="https://app.kravos.ai/sdk/v1/loader.js" data-api-key="spk_..." data-position="bottom-right" async></script>

For the in-app suite surface, add data-mode="suite". The dashboard uses side-panel for suite installs.

<script
  src="https://app.kravos.ai/sdk/v1/loader.js"
  data-api-key="spk_..."
  data-mode="suite"
  data-position="side-panel"
  async
></script>

Supported data attributes:

AttributeValuesNotes
data-api-keyAgent-scoped key with chat permissionRequired
data-modesuiteOmit for launcher mode
data-positionbottom-right, bottom-left, side-panelMobile uses a bottom sheet layout
data-base-urlKravos web app originOptional; use only when instructed by Kravos.ai support

Direct iframe

Use a direct iframe when your app already owns the launcher button or page layout. You must size and position the iframe yourself.

<iframe
  src="https://app.kravos.ai/widget?key=spk_..."
  title="Chat Widget"
  allow="microphone; speaker-selection"
  sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
></iframe>

Add &mode=suite for the suite surface. The widget route only reads key and mode; placement is handled by the loader or by your host page CSS.

Package factory

The repo includes @kravos.ai/sdk with createChatWidget, useWidget, useChat, and

RealtimeConnection. The package is not currently distributed for customer use; use the script or iframe integration instead.

import { createChatWidget } from '@kravos.ai/sdk'

const widget = createChatWidget({
  apiKey: 'spk_...',
  baseUrl: 'https://app.kravos.ai',
  mode: 'launcher',
  position: 'bottom-right',
  user: { name: 'Jane Doe', email: 'jane@example.com' },
  context: { pageUrl: window.location.href, pageTitle: document.title },
})

widget.open()
widget.setUser({ email: 'new@example.com' })
widget.setContext({ pageUrl: window.location.href })
widget.destroy()

Realtime hooks are low level

useChat and RealtimeConnection manage socket messages and typing state. The current useChat().sendMessage() only adds an optimistic local message and stops typing; it does not call the hosted chat streaming endpoint for you.

Configuration

Most widget behavior is dashboard-managed and stored on the selected agent. The runtime reads that config during

POST /api/sdk/init.

AreaRuntime behavior
AgentSelected by the agent-scoped API key
Surfacelauncher by default, suite when mode=suite
PlacementLoader supports bottom-right, bottom-left, and side-panel; mobile is bottom
ThemePrimary color, header text, bubbles, input colors, font, border radius
BrandingTitle, subtitle, logo URL, and powered-by badge
BehaviorGreeting and input placeholder
Pre-chatOptional required name, email, and phone fields before chat starts
VoiceLauncher voice option when widget or agent voice config is enabled

Some saved schema fields are not currently applied by the hosted runtime, including persistSession,

showTimestamps, avatarUrl, and iconColor. The dashboard also exposes auto-open settings, but the current script loader starts minimized. Use package or loader programmatic control if you need to open the widget from your own event.

Identity and External IDs

By default, the widget creates or resumes an anonymous embedded user using a browser session id stored under

single_chat_session_id. Passing unsigned user data can fill name, email, and phone, but it is not proof of identity.

For logged-in products, use signed embedded identity. The iframe accepts identityToken through

identify() or a single-chat:identify postMessage. The server verifies a short-lived HMAC token with these claims:

{
  "tenantId": "tenant_...",
  "agentId": "agent_...",
  "externalUserId": "user_123",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "avatarUrl": "https://example.com/jane.png",
  "claims": { "plan": "pro" }
}

Issue the token on your server, never in browser code. This app verifies signed identity, but it does not expose a public endpoint that creates identity tokens for you. If Kravos.ai has not configured an issuer for your account, use anonymous sessions or unsigned profile fields instead.

Conversation Lifecycle

Launcher mode creates or resumes the latest open web text conversation for the session. The user can end the chat, which closes the conversation and shows a 1–5 star feedback form with an optional comment.

Suite mode adds conversation history. It can list, create, open, rename, archive, and search the embedded user's web text conversations. The user's last opened suite conversation is stored in embedded preferences.

Important routes used by the widget and suite:

RoutePurpose
POST /api/sdk/initCreates/resumes session, user, config, preferences, history
POST /api/chat/streamSends a text message and streams the AI response
GET /api/sdk/conversationRefreshes the active launcher conversation
PATCH /api/sdk/conversationCloses a launcher conversation
POST /api/sdk/new-chatStarts a fresh text conversation
GET/POST /api/sdk/conversationsLists or creates suite conversations
GET/PATCH /api/sdk/conversations/:idReads, renames, or archives a suite conversation
GET /api/sdk/conversations/searchSearches suite conversation titles and messages
GET/PATCH /api/sdk/preferencesReads or updates locale, sidebar state, and last conversation
PATCH /api/sdk/userUpdates unsigned user fields for the current session
POST /api/sdk/feedbackStores conversation-level rating and optional comment
POST /api/sdk/voice/startStarts an ElevenLabs-backed web voice conversation
POST /api/sdk/voice/endEnds the voice session and stores client transcript fallback

Voice in the Widget

Voice appears in launcher mode when widget voice or the agent voice config is enabled. Starting voice requires:

  • an agent voice configuration with an ElevenLabs agent
  • ELEVENLABS_API_KEY configured server-side
  • enough hosted credits and voice entitlement
  • microphone permission in the browser
  • an iframe or loader with microphone permission

If voice fails to start, the launcher falls back to text chat. Suite init currently reports voice support as disabled.

Auth, CORS, and Domain Troubleshooting

SymptomCheck
API key is requiredThe iframe URL needs ?key=spk_..., or the script needs data-api-key.
401 Invalid API keyThe key is missing, revoked, expired, wrong prefix, or lacks chat permission.
403 agent-scoped API keySDK routes require an agent-scoped key. Organization-scoped keys are for other API surfaces.
403 Origin is not allowedAllowed origins are exact strings. Use origins like https://app.example.com, not paths or trailing slashes.
Widget works in sandbox onlyDashboard session fallback can hide key/domain issues. Test with the production script on a real staging URL.
Cross-origin API calls failThe hosted widget calls /api/sdk/* from inside the iframe. Contact Kravos.ai support before making direct browser calls from your app.
Voice button missingConfirm launcher mode, widget/agent voice enabled, and voice config is complete.

If you configure an origin allowlist, include the Kravos web app origin that serves /widget. Include your product origin too only if your page directly calls SDK routes or hosts the loader from that origin.

Before You Go Live

  • create a dedicated agent-scoped chat key for the widget
  • verify allowed origins with the exact staging and production origins
  • test launcher and suite modes separately if you use both
  • check desktop, mobile, and side-panel placement on real pages
  • confirm pre-chat fields are only the fields support teams actually need
  • test signed identity with one returning user and one anonymous user
  • start and end a voice session if voice is enabled
  • submit feedback and confirm it appears in Feedbacks

API Keys

Create agent-scoped keys, set permissions, and manage allowed origins.

Conversations

Review text, suite, and voice conversations after users chat through the widget.

Voice Lab

Test voice sessions, debug tool calls, and manage ElevenLabs sync before enabling widget voice.

API Reference

Compare dashboard-domain widget routes with the public server-to-server API.

Last updated: August 2026