Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kontext.so/llms.txt

Use this file to discover all available pages before exploring further.

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

1. Wrap your app in <AdsProvider>

<AdsProvider> initializes a session that’s available to every component inside it via the useAds() hook. Place it high enough in your tree so it can contain all ad placements.
import { AdsProvider } from '@kontextso/sdk-react'

function App() {
  return (
    <AdsProvider
      publisherToken="<your-publisher-token>"
      userId="user-1234"
      conversationId="conv-5678"
      character={{
        id: 'character-1234',
        name: 'John Doe',
        avatarUrl: 'https://example.com/avatar.png',
        greeting: 'Hello, how can I help you today?',
      }}
      onEvent={({ name, code, payload }) => {
        // process events
      }}
    >
      <TheRestOfYourApplication />
    </AdsProvider>
  )
}

2. Feed messages to the SDK

The SDK preloads ads in response to new chat messages. Call addMessage() from the useAds() hook whenever a user or assistant message is created.
import { useAds } from '@kontextso/sdk-react'

const { addMessage } = useAds()

// Call this on every user and assistant message in the conversation.
addMessage({
  id: '<unique-message-id>',
  role: '<user | assistant>',
  content: '<content of the message>',
  createdAt: new Date(),
})

3. Mount <InlineAd>

An ad slot is a designated area in your UI where an ad can be rendered. In most cases, it appears below an assistant message. Place <InlineAd /> wherever the ad should appear and pass the messageId of the assistant message it’s associated with.
import { InlineAd } from '@kontextso/sdk-react'

function MessageList({ messages }: { messages: Message[] }) {
  return (
    <div>
      {messages.map((m) => (
        <div key={m.id}>
          <Message message={m} />
          {m.role === 'assistant' && <InlineAd messageId={m.id} />}
        </div>
      ))}
    </div>
  )
}

Observing events

Subscribe to ad lifecycle events via the <AdsProvider> onEvent prop. Every event has a stable name and a typed payload:
<AdsProvider
  // ...
  onEvent={(event) => {
    switch (event.name) {
      case 'ad.filled':
        console.log('filled:', event.payload.id, 'revenue=', event.payload.revenue)
        break
      case 'ad.clicked':
        console.log('clicked:', event.payload.url)
        break
      case 'ad.no-fill':
        console.log('no fill, skipCode=', event.payload.skipCode)
        break
    }
  }}
>
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.