Skip to main content
This is the 5-minute integration walkthrough. Before you start, make sure you’ve completed Installation.

1. Create a session

Import createSession() to configure a session for a specific user and conversation. The returned Session is the entry point for everything else — feeding messages, creating ads, listening to events.
If you’re using the CDN global:
Notes:
  • userId should stay the same for the same user across sessions/devices — it powers personalization, frequency capping, and rewarded ads.
  • conversationId should be unique per chat thread (a single chat room, support ticket, or conversation in your app).

2. Feed messages to the SDK

The SDK preloads ads in response to new chat messages. Call addMessage() whenever a user or assistant message is created — both roles are needed for Kontext to understand conversation context.
Notes:
  • id must be unique per message and stable — the same id is referenced later when you create an ad.

3. Mount an ad

To display an ad, create an Ad instance bound to the assistant message it should appear under, then mount it into a DOM element. The SDK manages the iframe and its lifecycle.
In a typical chat UI you’ll:
  1. Render your message list.
  2. For each assistant message, render a placeholder <div> for the ad.
  3. Call session.createAd(messageId) once the placeholder DOM exists, then ad.mount(element).
  4. When the message scrolls off-screen or the conversation ends, call ad.destroy() to release the iframe.
If you’d rather do it in one call, session.render({ messageId, element, theme }) is a convenience wrapper around createAd + mount.

4. Tear down

Call session.destroy() when the conversation ends or the page unmounts. Idempotent and required to cancel in-flight preloads and release iframe resources.

Observing events

Subscribe to the lifecycle of every ad via the onEvent callback. Every event has a stable string name and a typed payload:
Every placement-attributed event (ad.filled, ad.viewed, ad.clicked, ad.render-*, video.*, reward.granted) also carries a top-level code field naming the matched placement, so publishers with multiple enabledPlacementCodes can disambiguate. Session-wide events (ad.no-fill, ad.error) omit it. For SDK-internal diagnostics during integration, also pass an onDebugEvent callback — it receives (name, data?) for every internal step the SDK takes.