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

# SDK Health

> What TagadaPay sees of your coded funnel: steps never reached, events that never arrive, blocked pixels, an outdated SDK — and how to fix each one

# SDK Health

A coded funnel fails quietly: a pixel blocked by your Content-Security-Policy, a step renamed in the code but not in the manifest, an Apple Pay domain never registered. The visitor sees nothing wrong and the numbers just drop. SDK health is the list of these silent failures, computed from what the Headless SDK reports from your visitors' browsers.

It is one report, shown in three places:

* on the [canvas](/developer-tools/funnels/canvas): the step cards and their drawer show the checks that concern them;
* in your terminal: `npx tagada funnel check`;
* in code: `tagada.funnels.health(storeId, funnelKey?)` from `@tagadapay/node-sdk`.

A store with no [coded funnel](/developer-tools/headless-sdk/coded-funnels) has no report: it answers `ran: 0` and the canvas shows nothing.

***

## From the terminal

```bash theme={null}
export TAGADA_API_KEY=sk_...
export TAGADA_STORE_ID=store_abc123
npx tagada funnel check
```

```
🟡 Pixel blocked by your CSP
   tiktok never loaded on shop.example.com: csp.
   npx tagada funnel csp
🟡 Step declared but never reached
   upsell was declared on 2026-10-02 and nobody has landed on it.
   node:sdkstep_8f2c1a
@tagadapay/headless-sdk      …            latest …       …
@tagadapay/core-js           …            latest …       …
@tagadapay/node-sdk          …            latest …       …
ran 12 checks
```

Each check prints its title, what was seen, and the fix. Then one line per package (`headless-sdk` and `core-js` as your visitors run them, `node-sdk` as it last pushed) with the latest version and how the two compare.

| Flag | What it does |
| - | - |
| `--funnel=<key>` | Only this funnel. Without it, every coded funnel of the store. |
| `--json` | Prints the raw report instead, and always exits `0`. |
| `--api-key=`, `--store=`, `--base-url=` | As for [`funnel push`](/developer-tools/headless-sdk/coded-funnels#5-push-the-manifest). |

The command exits `1` when at least one check is an error, so you can run it in CI after a deploy.

***

## The report

```typescript theme={null}
{
  status: 'error' | 'warning' | 'ok',   // the worst severity present
  ran: number,                          // how many checks were evaluated
  checks: Array<{
    id: string,                         // e.g. 'pixel-blocked'
    severity: 'error' | 'warning' | 'ok',
    title: string,
    detail: string,
    fix: { kind: 'command' | 'prompt' | 'canvas' | 'link', value: string },
    scope: string,                      // what it is about, see below
    firstSeenAt: Date | null,
    lastSeenAt: Date | null,
  }>,
  packages: Array<{ name: string, version: string | null, latest: string,
                    state: 'current' | 'recent' | 'outdated' | 'unknown' }>,
}
```

* `fix.kind` says how to read `fix.value`: a command to run, an instruction to give your developer or your AI assistant, a place on the canvas (`node:<card id>`, `flow:<store id>`), or a CRM page.
* `scope` is `sdk` (the whole funnel), `step:<funnel>/<step>`, `event:<funnel>/<step>/<event>`, `destination:<provider>`, `wallet:applePay` or `wallet:googlePay`.
* A check that cannot be evaluated — no data yet, a provider that did not answer — is left out, never reported as `ok`.
* For packages, `current` is the latest release or any newer version, `outdated` is a major or three minors behind the latest, `recent` is anything in between, and `unknown` means no version was reported.

***

## The checks

The signals behind these checks are what the SDK sends from your visitors' browsers, kept at most once a minute each. "Recently" means in the last 7 days.

### Errors

| Check | What it means | Fix |
| - | - | - |
| `sdk-no-traffic` — SDK has never sent anything | The funnel is declared, and no browser has ever reported anything for this store. Either the site is not live yet, or the pages never call `track.step()`, or they run another store id. | Call `track.step()` on every step, deploy, open a page, and run `npx tagada funnel check` again. |
| `sdk-version-unknown` — SDK version not reported | Signals arrive, but none carries an SDK version: the site runs a Headless SDK older than the `track` module. | Upgrade `@tagadapay/headless-sdk` to 1.16.0 or later and redeploy. |
| `secret-key-in-browser` — Secret key used from a browser | A request from a browser carried an `Authorization` header. Your secret API key is in your front-end code. | Revoke the key in Settings → API keys now, then keep keys on your server only. |
| `wallet-applepay-domain` — Apple Pay domain not registered | Apple Pay is on in the payment flow, and one of the manifest `domains` is not registered for it: the Apple Pay sheet fails on that domain. | Register the domain from the payment flow of the store. See [Wallets](/developer-tools/payments/wallets). |
| `wallet-googlepay-domain` — Google Pay domain not registered | Google Pay runs through Stripe, and one of the manifest `domains` is not registered at Stripe. | Register the domain from the payment flow of the store. |
| `checkout-no-processor` — Checkout has no active processor | The payment flow of the store has no enabled processor: nobody can pay. | Add or re-enable a processor in the payment flow. |

### Warnings

| Check | What it means | Fix |
| - | - | - |
| `sdk-outdated` — Headless SDK is outdated | Your visitors run a version a major, or three minors, behind the latest. Not raised during the week after a release. | Upgrade `@tagadapay/headless-sdk` and redeploy. |
| `manifest-drift` — Deployed manifest is not the declared one | The browsers recently reported a manifest TagadaPay was not given: the site was deployed without pushing. | `npx tagada funnel push` |
| `origin-unknown` — Events from an undeclared domain | A host not listed in `domains` recently sent events. They were ignored. | Add the host to `domains`, then push. |
| `wallet-unavailable` — Wallet button never appeared | Apple Pay, Google Pay or the express checkout is configured, and recently its button was never built on the checkout page. A visitor whose device does not offer a wallet does not count. | Check why the express button is not rendered on your checkout page. |
| `step-never-seen` — Step declared but never reached | A step declared more than 24 hours ago has never been reached, while the funnel has traffic. Often a step id in the code that differs from the manifest. The card shows a **Never seen** pill. | Call `track.step('<id>')` with the manifest id on that page. |
| `step-undeclared` — Step seen but not declared | The code recently reported a step id that is not in the manifest. It is on no card. | Add the step to the manifest and push, or fix the id in the code. |
| `event-never-received` — Declared event never arrives | An event declared in the manifest more than 24 hours ago has never fired, while its step is reached. | Call `tagada.track.event('<name>')` on that step. |
| `pixel-blocked` — Pixel blocked by your CSP | A bound pixel recently failed to load on your site: blocked by the Content-Security-Policy, a load error, or a timeout. | Allow the pixel's origins — see [Content-Security-Policy](/developer-tools/headless-sdk/csp). |
| `pixel-duplicate` — Pixel fired twice | Your code loads a pixel that TagadaPay also loads, so events count twice. | Remove the tag from your code, or unbind that pixel on the canvas. |

***

## In the browser

`tagada.track.health()` answers for the current page only, without asking the server: whether tracking is on, the funnel key, which pixels loaded, and what was blocked on this page. Use it while you develop; use `funnel check` for what happens across all visitors.


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