MenuVerify your installation

Installation guides

Verify your installation

Check that ProductLense records your visits, and fix the common reasons a pageview does not arrive.

After adding the script, confirm three things: the script loads, the browser sends events, and ProductLense accepts them. This page walks through each check and lists every reason an event can be refused or silently skipped.

The three checks

  1. Open your site in a normal browser window (not a private window with strict blocking, and not on localhost).
  2. In the browser's developer tools, open the Network tab and reload. Look for a.js from api.productlense.app with status 200, then a POST to https://api.productlense.app/api/e. The script batches events for up to one second, so the request appears shortly after load or when you leave the page.
  3. Open the Live page in the ProductLense dashboard. Your visit appears within a few seconds.

A 204 response means ProductLense accepted the batch. Anything else carries a JSON error with a message:

JSON
{ "ok": false, "error": { "code": "invalid_input", "message": "hostname not allowed for this site" } }

If the request is refused

Status and messageCauseFix
400 hostname not allowed for this siteThe page's hostname is not one of the site's hostnames.Add it in Settings → Sites. A bare example.com also admits www.example.com; *.example.com admits every subdomain and the apex.
400 origin not allowed for this siteThe request's Origin (or Referer) is a hostname the site does not list.Same fix: add the hostname the page is served from.
400 s must be a site uuiddata-site is mistyped or still SITE_ID. (Without any data-site, the script sends nothing.)Copy the id again from Settings → Sites.
404 unknown siteThe site id does not exist, or the site was deleted.Use the id of an existing site.
413 body exceeds 8 KBA batch with very large props.Keep props small: at most 2 KB per event.
429 quota_exceededThe account used its monthly events plus the 10% grace band.Upgrade, or wait for the next month; Retry-After gives the seconds until it starts. See plans and limits.
503 rate_limitedThe ingest queue was briefly full.Nothing to do; the next batch goes through.

If nothing is sent at all

The script skips sending in these cases, by design:

  • The page runs on localhost. Add data-dev="true" to the tag to test locally, and remove it before deploying.
  • navigator.webdriver is true: Playwright, Puppeteer, Selenium and similar automation.
  • window.__pl_disable is set before the script runs. Some teams set it for their own staff.
  • The path matches a data-exclude glob. See exclude pages.
  • The tag has type="module", or a bundler or optimisation plugin rewrote it. The script reads its settings from its own classic <script> tag, so it must stay exactly as given.
  • An ad or privacy blocker in your own browser blocks api.productlense.app. Try another browser profile. To reduce blocking for visitors, see proxy the script through your own domain.

If the request succeeds but the visit is missing

  • Bots are dropped silently with a 204, so that they never cost you quota. A user agent containing bot, crawl, spider, preview, headless, lighthouse, curl/ and similar markers is treated as a bot, and so is an empty user agent. Test from a normal browser. See bots and filtering.
  • The Live page shows the last 30 minutes. For an older visit, open the Overview with Today selected and no filters.

Content Security Policy

If your site sends a Content-Security-Policy header, the browser console shows a violation when ProductLense is blocked. Allow both the script and the endpoint it posts to:

Text
script-src 'self' https://api.productlense.app;
connect-src 'self' https://api.productlense.app;

If you use the inline queue stub, allow it too, for example by adding its sha256- hash to script-src.

Caching and optimisation plugins

Page caches can serve an old version of your pages without the script; purge the cache after installing. Plugins that combine, minify, defer or delay JavaScript (common on WordPress) can rewrite the tag. Exclude api.productlense.app/a.js from them.

Still stuck

Send the page URL and the status and message from the POST /api/e response through the contact page.

    ↑ ↓ to move, Enter to open