# It's not working

Find what you see below. Each section says why it happens, how to fix it, and how to confirm the fix. Start with the **Is it working?** check in Settings › Channels: keep it open while you load your site in another tab.

## What the check can and can't see

The check reports only what reaches the Telltale server:

- **The script was fetched.** When a page loads `sdk/v1.js`, the server notes the page's address, if the browser sends it (most do). This is the **Script loaded on** step.
- **A session started.** The SDK started on an allowed page with a valid key. This is **First session received** once its first events arrive.
- **A request was refused.** The page address is not on your Site's list, or the key belongs to no Site. The check says which.
- **A user was linked.** A session has a signed-in user or account. This is **Signed-in user linked**.

It cannot see what happens only inside the browser. A Content Security Policy block, a held tag waiting for consent, or an ad blocker all look the same from the server: the script loaded (or not even that) and no session started. When the check shows "script loaded" but nothing after it, it is telling you to look in the browser. Open DevTools on your site and check the Console and Network tabs.

## Nothing arrives at all

**What you see.** The check stays at its first step. No **Script loaded on** line appears.

**Why.** The page never asked for the script. Usually the tag is not on the page you opened: it was saved but not published, it is in the wrong file or theme, a cache still serves the old page, or a blocker stopped the request.

**Fix.**

1. Open your site, right-click, choose View Page Source, and search for `sdk/v1.js`. If it is missing, go back to your platform's install page: [Next.js](/docs/nextjs), [React](/docs/react), [WordPress](/docs/wordpress), [Shopify](/docs/shopify), [Webflow](/docs/webflow), [Google Tag Manager](/docs/gtm).
2. If it is there, open DevTools › Network, reload, and filter for `sdk`. A request marked blocked usually means an extension or a Content Security Policy (see below).
3. Publish (Webflow, GTM), clear your cache (WordPress), or edit the published theme (Shopify).

**Confirm.** View Page Source shows the tag, and DevTools › Network shows `sdk/v1.js` with status 200.

## The page address isn't on the allowed list

**What you see.** The check says requests were refused because the page address is not on the Site's list, and names that address. Or it says the script loaded on a nearby address, such as the `www` version of your domain. In DevTools › Network, `api/sdk/init` answers 403 ("Site key or origin not allowed"). The Console may also report it as a CORS error, because a refused request gets no CORS header.

**Why.** Your key only works on the addresses you listed for the Site. The match is exact: scheme, host and port. `https://www.example.com`, `https://example.com`, `http://example.com` and `https://example.com:8443` are four different addresses. Staging domains, `myshopify.com` and `webflow.io` addresses, and preview deployments are different too.

**Fix.** Go to Settings › Channels › Website addresses and add every address visitors use, exactly as it appears in the browser's address bar (up to the first `/`). For staging or `localhost`, a separate Site keeps test traffic out of your real numbers.

**Confirm.** Reload the page. `api/sdk/init` answers 200 and the check shows **First session received**.

## The key is wrong or was changed

**What you see.** The check says requests came in with a key no Site has. Or DevTools › Network shows `api/sdk/init` answering 403 ("Site key or origin not allowed"), often also reported in the Console as a CORS error, while the page address is on your list.

**Why.** The tag's `data-telltale-key` does not match a current publishable key: a typo, a copy from another Site or workspace, a key that was rotated, or the server key (`ao_sk_...`) pasted by mistake.

**Fix.** Copy the tag again from Settings › Channels, which has the current key filled in, and replace the whole tag. The browser always uses the publishable key (`ao_pk_...`). If the server key was ever on a page, rotate it (see [Authentication and keys](/docs/authentication)).

**Confirm.** `api/sdk/init` answers 200 and the check moves to **First session received**.

## The script waits for consent

**What you see.** **Script loaded on** appears, but no session follows. There are no errors in the Console. `api/sdk/init` never appears in DevTools › Network.

**Why.** The tag has `data-telltale-wait-for-consent` (or `waitForConsent: true`), so it sends nothing until your banner calls `optIn()`. That is the intended behaviour. Either the banner has not been answered, the visitor refused, or nothing calls `optIn()`.

**Fix.**

1. Accept measurement in your banner and reload.
2. In the Console, run `window.Telltale.getClient().status().consent`. `held` means nobody has called `optIn()`; `withdrawn` means `optOut()` was called or a refusal is saved.
3. Make sure your banner's "allowed" callback calls `window.Telltale.getClient().optIn()`. See the [Consent bridge guide](/docs/consent) and the recipes for [OneTrust](/docs/consent-onetrust), [Cookiebot](/docs/consent-cookiebot) and [Sourcepoint](/docs/consent-sourcepoint).

If your site has no banner, remove `data-telltale-wait-for-consent`. Do not remove it to get around a banner you do have.

**Confirm.** After you accept, `status().consent` is `granted` and the check shows **First session received**.

## A Content Security Policy blocks it

**What you see.** The Console shows a message such as "Refused to load the script" or "Refused to connect" naming the Telltale server. The check shows no session, and may not show **Script loaded on** either.

**Why.** Your site's Content Security Policy does not list the Telltale server. A blocked script never loads; a blocked connection loads the script but stops every request.

**Fix.** Add the Telltale server, `https://app.trytelltale.dev`, to `script-src` and to `connect-src` (and to `script-src-elem` if your policy has one), or use a nonce with `'strict-dynamic'` plus `connect-src https://app.trytelltale.dev`. Never add `'unsafe-inline'` or `'unsafe-eval'`. The [Content Security Policy guide](/docs/csp) has both options.

**Confirm.** Reload with the Console open: no violation names the Telltale server, and the check shows **First session received**. Two `blob:` worker reports are expected if you did not allow `worker-src blob:`; they do not stop collection.

## Sessions arrive but no signed-in user is linked

**What you see.** **First session received** is done, but **Signed-in user linked** never completes.

**Why.** Nothing has told Telltale who is signed in yet. Either identify is not set up, it runs before your auth knows the user, it runs while the tag is held for consent (it is then ignored), or you tested while signed out.

**Fix.**

1. Sign in to your own site as a test user, then browse a page.
2. Recommended: link the session from your server after sign-in ([Quickstart step 2](/docs/quickstart#2-attach-identity-from-your-own-authentication), [Server API › Associate identity](/docs/server#associate-identity)).
3. Or in the browser: call `window.Telltale.getClient().identify({ userId, accountId })` once your auth knows the user, inside `try { ... } catch {}`, and again after `optIn()` on a held tag. Platform examples are on each install page.

Use opaque, stable internal IDs. Never send e-mail addresses, names or phone numbers.

**Confirm.** The check shows **Signed-in user linked**, and the session opened from it shows the user and account IDs.

## It works on one page but not others

**What you see.** Sessions arrive from some pages only.

**Why.** The tag was added to one page or template instead of the whole site: a Webflow page's settings, a single Next.js page, a Shopify section file, or a WordPress snippet limited to some pages.

**Fix.** Move the tag to the site-wide place: Webflow Site settings, the Next.js root layout, Shopify's `layout/theme.liquid`, WordPress's Header box or `wp_head`, or a GTM trigger on All Pages.

**Confirm.** View Page Source on a page that was missing it now shows `sdk/v1.js`.

## It works locally but not on the live site

**What you see.** It works on `localhost` or staging, not in production (or the other way round).

**Why.** Usually each address needs to be on the Site's list (see [the allowed list](#the-page-address-isn-t-on-the-allowed-list)), or the live site has a Content Security Policy, a cache or an optimisation plugin that your local build does not.

**Fix.** Add the live address under Settings › Channels › Website addresses, clear caches, and exclude `sdk/v1.js` from script-delaying or combining features. Keep local and staging on a separate Site.

**Confirm.** The live address appears under **Script loaded on** and then **First session received**.

## Ad blockers and privacy extensions

**What you see.** It works for you in one browser and not another, or for some visitors only. DevTools › Network shows the script request blocked by the client.

**Why.** Some extensions block third-party scripts. Telltale does not try to get around them: when a visitor's browser blocks it, nothing is collected for that visitor.

**Fix.** Test in a private window with extensions turned off. Nothing to fix for visitors.

**Confirm.** The test window produces **First session received**.

## Shopify checkout pages show nothing

**What you see.** Sessions show product, cart and account pages, but never checkout, thank you or order status.

**Why.** Shopify does not run theme code on its checkout pages, so the tag cannot load there. See [Install on Shopify › Checkout](/docs/shopify#checkout-thank-you-and-order-status-pages).

**Fix.** Nothing to fix. Protect the steps before checkout: account, cart and product pages.

**Confirm.** Not applicable.

## The dashboard says Unknown

**What you see.** Sessions arrive, but the verdict is **Unknown** rather than **AI agent** or **Human**.

**Why.** Unknown means the evidence was not enough to say either way, often because the visit was short or had little interaction. Unknown is not human. Telltale needs evidence from a real device before it says Human. (The public demo shows this as "Monitoring" or "More activity needed".)

**Fix.** Nothing is broken. Browse for longer, click and type as a visitor would, and the verdict can change. For a protected action, decide what Unknown means in Control › Rules; never treat it as Human.

**Confirm.** A longer test visit by a person on a physical device usually ends Human; one driven by an automated browser ends AI agent or Unknown. See [Verdicts and authorization](/docs/verdicts).

## Telltale for MCP servers: no calls arrive

**What you see.** **Settings › Channels › MCP server › Is it working?** still says "Waiting for the first call" after an agent called a tool.

**Why.** The wrapper sends calls from your server in batches, usually within five seconds. Nothing arrives when the key is wrong (a publishable `ao_pk_` key, or a server key that was rotated away: the batch is refused with 401 and dropped), when your server can't reach the Telltale server, or when the server isn't wrapped where the tools are registered.

**Fix.** Use the Site's server key from Settings › Channels › Server keys, kept in your server's environment. Turn on `debug: true` (or `TELLTALE_DEBUG=1`) and read stderr: each batch logs how many calls were accepted, replayed and rejected. A rejected call names its field in the answer's `rejected[]` list (index, field, error), and the rest of the batch is still recorded; an adapter older than the server is the usual cause, so download it again.

**Confirm.** Make one tool call from any MCP client and the check turns to "Working" with the time of the last batch. More cases (no accounts, "Not declared" clients, calls counted twice) are in [Telltale for MCP servers](/docs/mcp#troubleshooting).

## Telltale for APIs: no calls arrive, or calls are held

**What you see.** **Settings › Channels › API › Is it working?** still says "Waiting for the first call", calls are refused, or a protected route answers with a hold.

**Why.** As with MCP: a wrong key or an unreachable Telltale server stops every batch. A call whose route is a raw path (`/v1/invoices/12345` instead of `/v1/invoices/:id`) is refused alone and listed in `rejected[]`. A route you protect asks your rule (Control › Rules) before the handler runs; with no saved rule an AI agent call is held for review by default, and Unknown is allowed.

**Fix.** Check the server key and turn on `debug: true`. Return route templates (or let the built-in normaliser do it). For held calls, approve them in Control › Approvals › Waiting, or settle them with your own check through the step-up endpoint; save a rule for the route if the default isn't what you want.

**Confirm.** One request to your API turns the check to "Working". More cases are in [Telltale for APIs](/docs/api-channel#troubleshooting).

## Still stuck

Collect what DevTools shows for `sdk/v1.js` and `api/sdk/init` (status code and response), and any Console messages that name the Telltale server, and email them to jad@heypharos.com. Never send your server key or a session token.
