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

# Troubleshooting

> Fix common Scanova Conversion Tracking issues — no events appearing, CORS errors, 403 domain errors, missing attribution, and duplicate events.

## Browser SDK issues

### No network request to `/ct` appears

Check these in order:

1. **Snippet is in the wrong place** — it must be in `<head>`, not `<body>` or after `</html>`
2. **`site_id` is missing** — confirm `scanova('init', 'YOUR_SITE_ID', ...)` has a real site ID, not a placeholder
3. **Script blocked by Content Security Policy (CSP)** — add `https://cdn.scanova.io` (script source) and `https://t.scanova.io` (connect source) to your CSP headers
4. **Browser extension blocking the request** — test in an incognito window with all extensions disabled
5. **`autoPageview: false` and no manual track call** — either enable `autoPageview` or add `scanova('track', 'pageview')`
6. **SDK loaded twice** — having both a direct HTML install and a GTM install on the same page causes issues. Remove one.

### `403 Domain not allowed`

The origin of your request is not in the tracking site's **Allowed Domains** list.

1. Go to **Integrations → Conversion Tracking**
2. Click on your tracking site → **Edit**
3. Add the exact hostname shown in your browser's address bar (e.g. `yoursite.com`, `www.yoursite.com`)
4. Save

<Note>
  `www.yoursite.com` and `yoursite.com` are treated as different domains. Add both if you use either.
</Note>

### `400` — Bad request

The `site_id` is invalid, empty, or the site has been deactivated in the dashboard. Verify:

* You are using the correct `site_id` for this tracking site
* The site is active (shown as enabled in the dashboard)

### Events appear in DevTools but not in the dashboard

* Wait up to 60 seconds — there is a short processing delay
* Ensure you are looking at the correct tracking site in the dashboard
* Verify `site_id` in the network request payload matches the site you are viewing

### Two events firing per page load

You have both `autoPageview: true` in your init options and a manual `scanova('track', 'page_view', ...)` call somewhere in your code. These produce two separate events. Remove one — see [Auto-Tracked Events](/conversion-tracking/browser/auto-tracking#page-view).

### No events at all for a specific visit

If no `/ct` request appears for a visit, the most likely cause is that the user arrived without a QR Code scan — there is no `?scnv=` parameter in the URL. The SDK checks for a `scan_session_id` before sending any event, and silently skips if it is absent.

Scanova Conversion Tracking only measures QR-scan-originated traffic. Direct or organic visits produce no events — this is by design.

To test attribution, visit your page with a `?scnv=` parameter to simulate a scan:

```
https://yoursite.com/?scnv=00000000-0000-0000-0000-000000000001
```

***

## Server-side event issues

### `401` — Missing API key

The `X-API-Key` header is not included in the request. See [Authentication](/conversion-tracking/api/authentication).

### `403` — Invalid key or wrong site

Either the key is invalid/revoked, or the `site_id` in your payload does not match the site that generated the key. Check:

* Copy the key again from the dashboard (keys are shown once — if you lost it, generate a new one)
* Verify `site_id` in your payload is the same site's ID shown in the API Keys tab
* Confirm the key has not been revoked

### `422` — Validation error

The response body tells you exactly which field failed. Common causes:

| Cause                           | Fix                                    |
| ------------------------------- | -------------------------------------- |
| `scan_session_id` is not a UUID | Must be a valid UUID string            |
| `event_name` is missing         | Required field for server events       |
| `properties` exceeds 10 KB      | Reduce payload size                    |
| Raw email in `properties`       | Hash it: `user_identifiers.email_hash` |

### Events delivered but not attributed to a QR Code

The `scan_session_id` you sent could not be linked to a QR scan in the Scanova database. This happens when:

* The `scan_session_id` was made up or invalid
* The user did not actually scan a QR Code — they arrived directly
* The scan session has expired

Confirm you are reading `scan_session_id` from the browser (via `localStorage._scnv` — an internal SDK storage key) and passing it to your server correctly. See [Send Server Events](/conversion-tracking/server/send-events#passing-scan_session_id-from-browser-to-server) for examples.

***

## Attribution issues

### Events show `null` for `qr_code_id`

This is an **orphan record** — the event arrived before the scan session data was fully propagated in the Scanova database. These records are automatically cleaned up after 24 hours if the session data never arrives, or backfilled once it does.

If you see many orphan records, check that:

* The `scan_session_id` in your events is a real scan session (not a test UUID)
* Your QR Codes are correctly linked to the tracking site in the dashboard

### Conversions showing for wrong QR Code

Your `scan_session_id` is not being read correctly — you may be reading a stale or incorrect value from `localStorage`. Confirm your frontend reads from `localStorage.getItem('_scnv')` (the SDK's internal storage key) and parses `.sid` from the JSON value. See [Send Server Events](/conversion-tracking/server/send-events#passing-scan_session_id-from-browser-to-server) for the full pattern.

***

## Performance issues

### `429` — Rate limit exceeded

You are hitting the rate limit:

* Browser events: 100 requests/min per IP
* Server events: 1,000 requests/min per API key

For server events, switch to the batch endpoint (`POST /server-events/batch`) to send up to 100 events per request, reducing your request rate by up to 100×.

For browser events, `429` during normal usage is rare. If you see it during load testing, space out your requests.
