Install the Kalman tag
Updated
The Kalman tag is a small first-party script. Once it's on your site, it records page views, the ad click IDs and UTM tags visitors arrive with, and any funnel steps you add. It never reads form fields, input values, page titles or page text.
Before you start
- You need to be an owner or admin of the workspace to change tracking settings.
- Your workspace needs to be live, with a plan chosen. Until then the tag's hits are refused (see Troubleshooting: no data).
- Optional but recommended: set up your own tracking subdomain first, such as
kl.northwindhealth.com. See Tracking domains. You can install the tag now and swap the snippet later.
1. Copy the snippet
- Open Integrations → Tracking.
- Find the panel 2. Install the script.
- Copy the snippet with the copy button.
The badge on that panel says fallback host while the tag loads from Kalman's own address, or first-party once your tracking domain is live. The text under it tells you which address it's loading from.
The snippet looks like this (yours has your own address in it):
<script>
!(function (w, d, u) {
w.kalman =
w.kalman ||
function () {
(w.kalman.q = w.kalman.q || []).push(arguments);
};
w.kalman.eventId =
w.kalman.eventId ||
function () {
return w.crypto && crypto.randomUUID
? crypto.randomUUID()
: Date.now().toString(36) +
Math.random().toString(36).slice(2);
};
var s = d.createElement('script');
s.async = 1;
s.src = u;
d.head.appendChild(s);
})(window, document, 'https://kl.northwindhealth.com/k.js');
</script>
It loads the tag in the background, so it doesn't slow your page down. Any kalman(...) calls made before the tag finishes loading are queued and sent once it has.
2. Paste it on every page
Paste it in the <head> of every page, including your intake and checkout pages if they're on your own site.
- Custom site: your shared layout or header template.
- Webflow or Framer: the site-wide custom code setting for the head.
- WordPress: a header code snippet plugin, or your theme's header.
On single-page apps you don't need anything extra. The tag records a page view whenever the address changes.
3. Allow your domains
The tag only accepts hits from domains on your Allowed origins list. Anything else is refused.
- On Integrations → Tracking, scroll to Privacy settings.
- In Allowed origins, enter one hostname per line, without
https://. For example:northwindhealth.com*.northwindhealth.com
- Press Save privacy settings.
A few things to know:
*.northwindhealth.comcovers subdomains such aswww.andstart., but notnorthwindhealth.comitself. List both.- If you gave your website address when you created the workspace, Kalman has already added both lines for you. Check the list anyway.
- Hosts you add under Intake domains are added to this list automatically when you save.
If your site has a Content Security Policy
A strict Content Security Policy (CSP) can block the tag without any visible error. These are the minimal entries for the snippet. Use your tracking subdomain, for example https://kl.yourbrand.com. Until that domain is active, the snippet loads from Kalman's app host instead (the host in the snippet's address, ending in /k/{site key}.js); add that host while you use it.
| Directive | Add | Why |
|---|---|---|
script-src |
https://kl.yourbrand.com |
The tag file (/k.js) |
script-src |
a nonce or a hash for the snippet | The snippet is a short inline loader |
connect-src |
https://kl.yourbrand.com |
Hits are posted to /c (fetch and sendBeacon) |
img-src |
https://kl.yourbrand.com |
A last-resort image fallback (/c.gif) |
Don't add 'unsafe-inline'. Instead, either:
- give the snippet's
<script>tag thenonceyour server already puts in its CSP (<script nonce="…">), or - add the SHA-256 hash of the snippet's exact contents to
script-src('sha256-…'). Copy the snippet once and hash it as it is: any change to it, even whitespace, changes the hash.
If you use the Kalman consent banner, it draws itself with inline style attributes. A style-src without 'unsafe-inline' hides its styling, so test the banner after changing your policy.
4. Verify the install
- On 2. Install the script, press Verify installation.
- In another tab, open any page of your site that has the snippet.
- The button changes to Waiting for the first page view…. Once Kalman gets a page view, it shows First page view received and when it arrived.
If nothing arrives after a minute or two, see Troubleshooting: no data.
What the tag never sends
- No form fields, typed values, page titles or page text.
- No full URLs. It sends the path only. Paths that match Sensitive paths (such as
/intake/**) are recorded as the pattern, and any part of a path that names a condition or medication is masked. - Only query parameters on Allowed query params are kept. For any others, only the parameter's name is noted so you can review it, never its value.
Next steps
- Add funnel steps and link visitors to their purchases: Track events.
- Pass click IDs into an intake on another domain: Click IDs and intake links.
Related articles
- Track funnel events with track and identifyWhen to fire each Kalman event, the fields it accepts, what gets dropped, where to paste the calls and how to check they arrived.
- Set up your tracking domainServe the Kalman tag from your own subdomain, like kl.northwindhealth.com: add a CNAME record, wait for Live, then swap your snippet.
- Click IDs, UTMs and intake linksHow Kalman keeps ad click IDs and UTMs, carries them into an intake on another domain with the auto-linker, and tags Meta ads.
- Troubleshooting: no data or nothing sentWhy the tag isn't recording, a tracking domain is stuck, or events aren't reaching an ad platform, and how to fix each case.
Support
Still stuck? Log in and open a request.
We answer in writing within one business day.
Open a request