> ## 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.

# Debugging

> Use onEvent for ad-lifecycle signals and onDebugEvent for a detailed internal log.

The SDK exposes two callbacks. Pick whichever you need.

## `onEvent` — public ad lifecycle

`onEvent` fires for the small set of public ad-lifecycle events: `ad.filled`, `ad.no-fill`, `ad.viewed`, `ad.clicked`, `ad.error`, plus the video and reward events. These are the ones you typically wire your UI and analytics to.

The complete list with payloads lives on [Ad lifecycle events](/concepts/events).

## `onDebugEvent` — detailed internal log

`onDebugEvent` fires for **every internal step** the SDK takes — preload requests starting and resolving, message-id pairing decisions, retry attempts, iframe loading milestones, and so on. It is verbose and not stable across SDK versions; treat it as a diagnostic log, not an API.

Wire it up only while you're investigating something, then turn it back off in production:

```ts theme={null}
onDebugEvent: (name, data) => {
  console.log('[kontext]', name, data)
}
```

## When something looks off

If an ad doesn't appear, fires the wrong event, or the SDK behaves unexpectedly:

1. Re-enable `onDebugEvent` in your build.
2. Reproduce the issue.
3. Capture the full `onDebugEvent` output and share it with us at [support@kontext.so](mailto:support@kontext.so).

The debug log is the fastest way for us to pinpoint what happened on your side without remote-debugging the integration.

## `skipCode` reference

When an `ad.no-fill` event fires, its payload carries a `skipCode` explaining why no ad was returned. The values you might see:

| `skipCode`        | Meaning                                                                                                            | What to do                                                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `ads_disabled`    | The SDK told the server ads are disabled for this request, because you called `addMessage` with `trackOnly: true`. | Expected in track-only mode.                                                |
| `ad_skipped`      | The server intentionally skipped this turn — typically because of [pacing](/concepts/pacing).                      | Expected; the next eligible turn will show an ad.                           |
| `ivt_blocked`     | An invalid-traffic check blocked the request.                                                                      | Real users shouldn't see this. If recurring in production, contact support. |
| `unfilled_bid`    | The auction ran but no bidder returned a usable ad.                                                                | Expected occasionally — fill rate is never 100%.                            |
| `illegal_content` | The conversation content was flagged as unsafe for ads.                                                            | Review the message text — some categories don't get ads.                    |
| `unknown`         | Catch-all for reasons we don't yet expose individually.                                                            | Capture the `onDebugEvent` output and send it to support.                   |
