Troubleshooting for developers
Every answer the collector, the server API and the raw event API give, and the common reasons a website sends nothing, with the cause and the fix.
Reference6 min read
Start with the browser's developer tools. On the Network tab, find the POST to collect (on api.bifrostorbit.com, or your own address with a proxy) and read its status and answer. Errors answer with { "error": { "code", "message" } }.
The script sends nothing
If there is no request to collect at all:
data-site, or the script didn't loadscript.js should answer 200 or 304.script.jsContent-Security-Policy blocks ithttps://api.bifrostorbit.com in script-src and connect-src.navigator.webdriver)localStorage['insights:off'] is set on your website. Open a page with #insights-on at the end of the address and confirm, or run insights.optIn() in the console.data-consent="wait" and the page hasn't called insights.consent()?insights-label= in the address)NEXT_PUBLIC_INSIGHTS_SITE, but the build ran without itNEXT_PUBLIC_ settings are fixed at build time, and CmsInsights renders nothing without a key. Set it for the build, or read the key as a server setting when the page renders.| Cause | Fix |
|---|---|
The script tag has no data-site, or the script didn't load | Check the tag. In Network, script.js should answer 200 or 304. |
An ad blocker or browser privacy setting blocked script.js | Try a private window without extensions. To lose fewer visitors, serve it from your own domain. |
Your Content-Security-Policy blocks it | The console says so. Allow https://api.bifrostorbit.com in script-src and connect-src. |
| The browser sends Do Not Track or Global Privacy Control | By design, nothing is sent. Switch it off to test. |
The browser is automated, such as Playwright, Puppeteer or Selenium (navigator.webdriver) | By design, nothing is sent from end-to-end tests. |
| The browser opted out, or was marked as your team's | localStorage['insights:off'] is set on your website. Open a page with #insights-on at the end of the address and confirm, or run insights.optIn() in the console. |
The script has data-consent="wait" and the page hasn't called insights.consent() | Call it once the visitor agrees, on every page. See The script. |
The tab is in labelling mode (?insights-label= in the address) | Labelling mode counts nothing. Open the page without it. |
A Next.js website reads the site key from NEXT_PUBLIC_INSIGHTS_SITE, but the build ran without it | NEXT_PUBLIC_ settings are fixed at build time, and CmsInsights renders nothing without a key. Set it for the build, or read the key as a server setting when the page renders. |
The script sends events up to two seconds after they happen, and at once when the page is hidden, so a request can appear a moment after the page loads.
Answers from collect
202 with accepted above 0202 with accepted: 0User-Agent, as from a proxy that doesn't pass it on), one of the site's excluded addresses, referrer spam, a data-centre address, or automatic events the site switched off400 invalid_json or invalid_eventsrevenue without currencyinsights.track. One bad event refuses the whole batch.403 wrong_originOrigin isn't one of the site's addresseswww. and the bare domain count as one, but *.northwilds.com doesn't include northwilds.com. For testing on your computer, add localhost.403 wrong_proxy_tokenINSIGHTS_PROXY_TOKEN and redeploy. See Serve Insights Orbit from your own domain.404 unknown_site413 too_large429 rate_limited| Status and code | Cause | Fix |
|---|---|---|
202 with accepted above 0 | Taken. Reports show it within a few seconds. | |
202 with accepted: 0 | Taken but left out on purpose: Do Not Track or Global Privacy Control, a bot (or a request without a User-Agent, as from a proxy that doesn't pass it on), one of the site's excluded addresses, referrer spam, a data-centre address, or automatic events the site switched off | What was left out on the overview counts each reason. From your own server or a VPN, the data-centre filter is the usual cause. |
400 invalid_json or invalid_events | The body isn't a batch the collector takes: over 50 events, a detail over the limits in Send your own events, or revenue without currency | Check what you send with insights.track. One bad event refuses the whole batch. |
403 wrong_origin | The page's address or the request's Origin isn't one of the site's addresses | Add the address under Site settings. www. and the bare domain count as one, but *.northwilds.com doesn't include northwilds.com. For testing on your computer, add localhost. |
403 wrong_proxy_token | Your proxy sent a token that isn't this site's, or one that was replaced or removed | Copy a new token from Site settings, First-party proxy, into INSIGHTS_PROXY_TOKEN and redeploy. See Serve Insights Orbit from your own domain. |
404 unknown_site | Wrong site key, or the site is in the bin | Copy the key from Install. Restore the site from Bin. |
413 too_large | The request is over 64 KB | Send fewer or smaller details. |
429 rate_limited | More than 120 requests a minute from one address | Usually a proxy without a token: every visitor shares your server's address. Add the proxy token. |
Visits arrive, but the numbers look wrong
CF-Connecting-IP, X-Real-IP or X-Forwarded-For, so there is no address to pass onX-Insights-Forwarded-For./insights/v1/collect on your own domain and answer 404src points to your domain, but data-api (api in CmsInsights) isn't set/stats/collect.POST to /stats/collect is redirectedtrailingSlash: true in next.config.ts/stats/collect/.history.pushState and the back and forward buttons. A router that changes the address another way isn't followed.history.pushState, as Next.js, React Router and most routers do.<meta name="insights-content">insightsMetadata(page) or CmsInsights page={page}. See Connect Insights Orbit with the CMS Orbit SDK.data-known-users| Symptom | Cause | Fix |
|---|---|---|
| Every visit is in your server's country, and visitors are low | A proxy or rewrites pass visits on without the visitor's address | Use a proxy route with the proxy token. |
| Visits stop after adding a proxy, and What was left out shows data centres | The collector sees your server's address, which is in a data centre | Add the proxy token, or switch Leave out data centres and hosting networks off. |
| The proxy has a token, but visits still show the server's country | Your website isn't behind a proxy that sets CF-Connecting-IP, X-Real-IP or X-Forwarded-For, so there is no address to pass on | Run it behind one, or pass the address yourself in X-Insights-Forwarded-For. |
Events go to /insights/v1/collect on your own domain and answer 404 | src points to your domain, but data-api (api in CmsInsights) isn't set | Set it to your collect address, such as /stats/collect. |
POST to /stats/collect is redirected | trailingSlash: true in next.config.ts | Use /stats/collect/. |
| A website that changes pages without reloading counts only the first page | The script follows history.pushState and the back and forward buttons. A router that changes the address another way isn't followed. | Change pages with history.pushState, as Next.js, React Router and most routers do. |
| Page views aren't tied to CMS Orbit entries | No <meta name="insights-content"> | Add insightsMetadata(page) or CmsInsights page={page}. See Connect Insights Orbit with the CMS Orbit SDK. |
| Known users don't show | The site doesn't have known users switched on, or the script has no data-known-users | See Send user ids for known users. |
Labelling mode
This labelling link has ended. Open labelling mode again from Insights Orbit.Labelling mode only works on the site's own addressesLabelled events are not in your organisation's plan.| Message | Fix |
|---|---|
This labelling link has ended. Open labelling mode again from Insights Orbit. | Labelling passes are short-lived. Open it again from Labels. |
Labelling mode only works on the site's own addresses | Open the page on one of the site's addresses. |
Labelled events are not in your organisation's plan. | Labels come with Growth and up. |
With your own proxy, pass on /labels, /label.js and /labelling as well as script.js and collect. createInsightsProxy and insightsRewrites do.
Server API, raw event API and GraphQL
401 unauthorizedAuthorization: Bearer ins_live_….403 wrong_scope403 not_in_plan404 unknown_site400 invalid_events400 invalid or invalid_cursortype isn't valid, from isn't before to, or a cursor came from somewhere else.429 rate_limited| Status and code | Cause |
|---|---|
401 unauthorized | No key, a wrong key, or a removed one. Send Authorization: Bearer ins_live_…. |
403 wrong_scope | The key may only send events, or only read them. Make a key that may do both under API keys. |
403 not_in_plan | Reading raw events comes with Growth and up. |
404 unknown_site | No site with that key in the key's organisation, or it is in the bin. |
400 invalid_events | A server event isn't valid: the message names the field, such as an event more than 7 days old, in the future, or with an address that isn't the site's. |
400 invalid or invalid_cursor | A date or type isn't valid, from isn't before to, or a cursor came from somewhere else. |
429 rate_limited | Over the key's limit per minute. Wait a minute. |
The API playground shows the same answers from your browser.
Was this page helpful?