> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trevosdk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# No events arriving

> Work out where the chain broke — the script, the key, the init call, or the track call.

**Data → Events** is empty, or the **Connect your app** drawer (topbar → **Connect SDK**,
or **Settings → SDK & install**) is still saying "Waiting for your first event…". Work down
this list in order; each step rules out everything above it.

## 0. Check the status chip in the topbar

It tells you where to start:

* `not connected` — the SDK never ran; start at step 1
* `SDK connected, no events` — key and network are fine; skip to the events step
* `receiving events`
* `SDK errors detected`
* `no recent events`
* `events rejected — old SDK key` — a deploy still ships a rotated key: update the env var
  and redeploy

From a terminal, or for a coding agent, the [CLI](/install/cli#check-an-sdk-install) asks the
same question:

```bash theme={null}
trevo connect --until loaded --wait   # passes once the SDK fetches its config
trevo connect --wait                  # passes once an event arrives
```

Run it, then load the app. It exits `0` when the SDK reports in, and `4` with a hint about what
to check if it doesn't. Config loaded but no event means skip to step 4.

## 1. Did the SDK load at all?

Open your browser console on a page where Trevo should be running:

```js theme={null}
typeof window.Trevo
```

* `"object"` — loaded. Go to step 2.
* `"undefined"` — the script never ran.

If you installed via a `<script>` tag, the global is **`Trevo`**. Check the Network tab for
the CDN request. The URL must include both the version and the filename:

```
✅ https://cdn.trevosdk.com/browser/v0.3.6/trevo.min.js
❌ https://cdn.trevosdk.com/browser/trevo.min.js
```

A `403` or `404` there means the URL is wrong, not that your key is wrong.

If you installed from npm, `window.Trevo` will not be set — that is normal. Confirm your
bundle actually imports the module instead.

## 2. Did `init()` run, and with a key?

```js theme={null}
Trevo.isReady()
```

`false` before config loads, `true` after. It does **not** warn when `init()` was never
called; to check that, call `Trevo.getVariant('anything')` and look for:

```
[TrevoSDK] getVariant() called before init(). Call TrevoSDK.init({ apiKey }) first. https://docs.trevosdk.com/sdk/setup
```

`init()` requires an explicit key. There is no auto-initialisation from a `data-key`
attribute:

```js theme={null}
❌ Trevo.init();
✅ Trevo.init({ apiKey: 'tsk_live_…' });
```

Calling `init({})` or `init({ apiKey: '' })` throws
`TrevoSDKError: init() requires a non-empty apiKey string.` — `init()` with no argument at
all throws a plain `TypeError`.

## 3. Is the key the right one?

Look at the Network tab for a request to `api.trevosdk.com/v1/config`.

| What you see | What it means |
| - | - |
| `200` | Key is valid and config loaded. Go to step 4 |
| `401` | Key is wrong, revoked, or the wrong class |
| `403` | Key is valid but the request's Origin isn't allowed for this workspace — set or fix the workspace domain in **Settings → Workspace** |
| no request at all | `init()` never ran — back to step 2 |

A `401` in a browser is most often a **server key in client code**. `tsk_secret_…` keys are
rejected when sent with an `Origin` header, because that combination means the key has been
shipped to a browser. Browsers need the publishable `tsk_live_…` key from
**Settings → SDK keys**.

A `401` right after rotating a key usually means the site was never rebuilt: hosts apply
env changes to *new* deployments only, so the live build keeps sending the old key until
you redeploy. [Where the key goes](/getting-started/quickstart#where-the-key-goes) has the
env var for each stack.

A successful config fetch is the strongest signal you can get before any event exists: it
proves the script loaded, the key is valid, and the workspace is reachable.
`trevo connect --until loaded` confirms it from the workspace's side.

## 4. Are you calling `track()`?

Nothing is captured automatically by `@trevosdk/browser` — no click tracking, no
pageviews. Two exceptions: `@trevosdk/react`'s provider emits one `page_view` on mount,
and exposures fire automatically inside `getVariant()`. A conversion exists only where you
wrote one:

```ts theme={null}
trevo.track('purchase_completed');
```

So if you see exposures but no conversions, the SDK is working and the missing piece is a
`track()` call on your side.

## 5. Are the events leaving the browser?

Watch the Network tab for `POST` requests to `ingest.trevosdk.com/v1/events`. Events are
**batched, not immediate** — a flush is triggered once 50 events are queued or about every
2 seconds, and on page unload; a single request carries up to 500 events. A single
`track()` in a quiet tab can take a couple of seconds to appear.

To force a send:

```js theme={null}
Trevo.flush()
```

| What you see | What it means |
| - | - |
| `202` | Accepted — check `rejected` in the body: individually invalid events are dropped and still return 202. `"reason":"daily_event_cap"` means the workspace passed its daily event cap and the batch was discarded; the cap resets at midnight UTC |
| `400` | The request envelope failed validation (missing `events`, empty array, >500 entries, unparseable body) — invalid events inside a well-formed envelope drop silently inside a 202 with a `rejected` count |
| `401` | Key problem, as in step 3 |
| `403` | Key is valid but the request's Origin isn't allowed for this workspace — set or fix the workspace domain in **Settings → Workspace** |
| `429` | Rate limited |
| nothing | The queue is empty; `track()` is not being reached |

## 6. Still nothing?

**Check for a blocker.** Ad blockers and privacy extensions block analytics-shaped
requests. Test in a clean profile with extensions disabled. If your users are blocked too,
consider recording conversions from your backend with
[`@trevosdk/node`](/install/node), which no blocker can intercept.

**Check for parked events.** Batches that couldn't be delivered before the page unloaded
(or before `destroy()`) are persisted in local storage and replayed on the next `init()`:

```js theme={null}
Object.keys(localStorage).filter(k => k.startsWith('trevo_'))
```

You'll see up to four keys:

* `trevo_anon_id` / `trevo_user_id` — identity (not key-suffixed)
* `trevo_config_cache_…` — cached config
* `trevo_failed_events_…` — undelivered batches

The sticky-assignment cache is `_trevo_variants_…` — its leading underscore means the
`trevo_` filter above misses it.

Batches rejected with 401/403/400 are dropped, not parked — an empty
`trevo_failed_events_…` key doesn't rule out an auth problem.

**Check for a slow network.** Requests time out after 10 seconds, and you will see this
warning in the console:

```
[TrevoSDK] Event flush failed  TimeoutError: signal timed out
```

## Quick reference

| Symptom | Most likely cause |
| - | - |
| `window.Trevo` undefined | Script tag URL wrong, or blocked |
| `init() requires a non-empty apiKey string` | Called `init()` with no argument |
| `401` on `/v1/config` | Secret key used in a browser, or a revoked key |
| Config `200`, no events | No `track()` call is being reached |
| Exposures but no conversions | The SDK works; the `track()` call is missing |
| Events in `trevo_failed_events_…` | Network or blocker, not configuration |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.