Install tracking on your website
1
Create a tracking token
Go to Settings → Tracking tokens and click New Token. Give it a Label that identifies the site or environment, such as “Production website”. Use one token per website or environment.
2
Copy the snippet
The token is shown once. Copy it now. The dialog also shows the embed snippet:
3
Add it to every page
Paste the snippet into your site’s
<head>, or into your site builder’s “custom code” setting. Single-page apps are handled: route changes count as pageviews.4
Restrict it to your domains (recommended)
Back on Tracking Tokens, open Manage allowed domains for the token and add your site’s hostnames, such as
example.com. Up to 20 domains per token. With no domains, all origins are allowed.The JavaScript API
The snippet also exposesICTrack for custom tracking:
identify declares who the visitor is. Because the snippet runs in the visitor’s browser, that declaration only counts when you turn on Trust identity declared by your site code (below).
How a visitor becomes a known contact
A visit is anonymous until one of three things happens. Each of them links the visit, and that visitor’s other visits of the same day, to the contact.- They arrive from one of your emails. When a campaign or journey links to a site listed in a tracking token’s Allowed Domains, InstantCampaign adds a signed visitor id to the link. A recipient who clicks through is recognized as that contact. Links to other domains are left untouched, so the id never reaches third parties. On by default; turn off Settings → Tracking tokens → Identify visitors who arrive from my emails to send plain links (see Privacy).
- They submit one of your forms. Any InstantCampaign form on the site identifies the visit: a popup or embedded form, a Form block on a hosted landing page, or the email step of a web push prompt. The address is captured by InstantCampaign’s own form endpoint, so this works without any setting, for new and existing contacts alike. Always on.
- Your site declares it.
ICTrack.identify(email), or an event or goal sent with anemail, identifies the visit when Settings → Tracking tokens → Trust identity declared by your site code is on. The email must belong to an existing contact; a declaration never creates one. This is how Salesforce Marketing Cloud Personalization treats identity declared by its sitemap. It is off by default because the tracking token is public: with it on, anyone who types another person’s email into a field your site passes toidentify()can attach their visit to that contact and start that contact’s Website Event journeys.
Privacy
Website measurement is first-party audience measurement that InstantCampaign runs for you as your processor. In the UK (the statistical-purposes exception) and in France (the CNIL audience-measurement exemption) that kind of measurement runs without a consent banner on conditions: your visitors are told what it is and who provides it, they can object easily, and visit-level data is kept only as long as needed and then aggregated. InstantCampaign gives you what each condition needs.- No cookies in the default Cookieless mode. A visitor is a server-side hash of your workspace, the IP address and the browser, which changes every day at midnight UTC. The raw IP address is never stored. A visitor id is stored only if you turn on Persistent with consent and the visitor agrees (see Recognising returning visitors).
- Country comes from the browser’s time zone, not IP geolocation. That’s why there are no city-level reports.
- Referrer query strings are dropped. Crawlers and bots are ignored.
Let visitors object
Put this link on your site, for example in your privacy policy or footer:ICTrack.optIn()). Settings → Tracking tokens shows the same link ready to copy. Hosted landing pages show their own line at the bottom when they measure visits: “This page measures visits anonymously. Opt out”, in the page’s language, followed by a Privacy policy link when you set a privacy policy URL (below).
Tell visitors in your privacy policy
Settings → Tracking tokens → Privacy policy text gives you a ready-to-paste paragraph, written from your current settings: InstantCampaign as your processor, the purposes (anonymous measurement, and linking a visit to a contact when the visitor arrives from your email, submits your form, or, only if you turned it on, is declared by your site code), the daily-changing hash with no cookie, how long visits are kept, and the opt-out link; while email links carry the visitor id it also says that in France such per-recipient links need the visitor’s consent. It’s an English template: adapt it to your policy and check it with your counsel. Settings → Tracking tokens → Visitor identity → Privacy policy URL is the address of your own privacy policy (it must start withhttps://). When it’s set, the consent banner and the footer line of your hosted landing pages link to it, and the paragraph above ends with “See our privacy policy at …”. Leave it empty for no link.
How long visits are kept
Visit-level records (visits, pageviews and anonymous events) are kept for 400 days (about 13 months). After that they’re reduced to daily totals per channel, source, device and country, and the individual records are deleted. Events that belong to a known contact stay on the contact. In the Website report, the totals for sessions, pageviews and time on page include those daily totals when the period reaches back that far (All time, or the comparison with a long period), and a line under the totals says how many sessions come from aggregate history. Visitors, bounce rate, identified visitors, the chart and every breakdown cover the visit-level records only, and so does any filter the daily totals don’t keep (browser, landing page, page, campaign tags and the like).Global Privacy Control and Do Not Track
Browsers that send Global Privacy Control or Do Not Track are still counted, anonymously, but never linked to a person: the visit isn’t attributed to a contact (not even from an email link),ICTrack.identify() is ignored, and events are recorded without a contact, so they start no journeys. If such a visitor submits one of your forms, the contact is still created or updated, because they gave you their details, but the visit isn’t attached to it. InstantCampaign publishes /.well-known/gpc.json to say it honours GPC. When the browser sends GPC, your hosted landing pages also say so at the bottom of the page: “Your opt-out preference signal has been honored”, in the page’s language, as California’s rules require from 2026.
Identify visitors who arrive from my emails
Settings → Tracking tokens → Identify visitors who arrive from my emails decides whether links in your emails carry the signed visitor id. In France the CNIL’s 2026 recommendation on email tracking treats per-recipient tracking links as needing the recipient’s consent, so turn the switch off for French recipients unless you collected that consent. The campaign send wizard’s tracking step carries the same note. With the switch off, clicks are still counted, but a visit that starts from an email is no longer attributed to the contact.What the scripts store in the browser
A/B tests store nothing: the variant a visitor sees is chosen on our server from the same daily hash, so a visitor keeps one variant for the day without any cookie. If your site has its own consent banner for other cookies, keep using it. The pages we host for you set no cookies unless you turn on Persistent with consent and the visitor accepts recognition.
Consent
The snippet keeps a consent state for every page view with two purposes:- Measurement (
analytics): the Website report. On by default, because it’s the exempt processor measurement described above. When your consent manager refuses it, the snippet sends nothing at all on that page. - Recognition (
identity): linking the visit to a contact and, with Persistent with consent, recognising the visitor across visits. Never on by default. When it’s refused, the visit stays anonymous whatever happens: email links,ICTrack.identify()and form submissions still work, but the visit isn’t attached to the contact.
ICTrack.consent() or the tag’s data-ic-consent attribute), IAB TCF v2.2, Google Consent Mode v2, then a known consent manager (OneTrust, Cookiebot, Usercentrics, Didomi, CookieYes, Klaro, iubenda). Nothing is stored by the snippet: your consent manager re-issues the choice on every page, and the snippet follows every change. Global Privacy Control and Do Not Track always switch recognition off. Every decision is kept as a consent record, and when the visitor becomes a known contact their decisions are added to the contact’s consent history.
Settings
Settings → Tracking tokens → Visitor identity has these settings:- Mode: Cookieless (the default, nothing changes) or Persistent with consent: visitors who agree to recognition get a visitor id and are recognised across visits (below), hosted pages show the consent banner, and every consent decision is recorded.
- Consent source: Auto-detect (read TCF, Consent Mode and the consent managers above), My site code (recognition waits until your page calls
ICTrack.consent()), or InstantCampaign banner on hosted pages. - Forget anonymous visitors after (days): how long a visitor id lives on our side without a visit, 30 to 395 days, 90 by default. Visits already linked to a contact stay linked.
- Require a marketing consent for identity: Auto (required while your workspace sends audiences to ad platforms), Always or Never. When required, recognition also needs the marketing category: TCF purposes 3 and 5, Consent Mode
ad_user_data, OneTrustC0004, Cookiebotmarketing, CookieYesadvertisement, iubenda purpose 5. - Privacy policy URL: your privacy policy, linked from the consent banner and the footer of hosted landing pages (see Tell visitors in your privacy policy).
Tell the snippet yourself
data-ic-consent sets how the snippet decides:
manual, the visit is measured anonymously and nothing is linked until you call ICTrack.consent({ identity: true }). With granted, consent managers are not read at all, but Global Privacy Control and Do Not Track still switch recognition off. Consent source: My site code in Settings has the same effect as manual on every tag that says nothing.
Recipes for consent managers
Every consent manager works in one of two ways. Pick one. Blocked until consent. You mark the tag with your consent manager’s own attribute andtype="text/plain" (or the type it asks for). The browser doesn’t run a text/plain script, so nothing at all is sent until the visitor agrees; then the consent manager turns it into a real script and the snippet starts as usual. The snippet finds its tag by data-site-id, so it doesn’t matter that the consent manager runs it late, and it reads its address from src, Klaro’s data-src or iubenda’s suppressedsrc. Once running, it still reads the consent manager, so a later refusal stops it and recognition follows the categories the visitor chose.
Let InstantCampaign read your consent manager. You paste the plain tag:
C0002).
OnetrustActiveGroups (C0002 for measurement, C0004 for the marketing consent) and follows OneTrustGroupsUpdated.
Cookiebot
Blocked until consent: the statistics category.
Cookiebot.consent.statistics (and marketing) and follows CookiebotOnAccept, CookiebotOnDecline and CookiebotOnConsentReady.
Usercentrics
Blocked until consent: add a data processing service named “InstantCampaign” in the Usercentrics admin and block the tag behind it.
UC_UI.getServicesBaseInfo() and follows UC_UI_INITIALIZED and UC_UI_CMP_EVENT. If you set a custom window event in Usercentrics, name it on the tag: data-ic-uc-event="myUcEvent".
Didomi
Blocked until consent: add InstantCampaign as a custom vendor in the Didomi console and use the id Didomi gives it.
didomiOnReady, reads Didomi.getUserStatus() (measurement = measure_content_performance; recognition also needs cookies, and select_personalized_ads or create_ads_profile for the marketing consent) and follows consent.changed.
CookieYes
Blocked until consent: the analytics category.
getCkyConsent().categories.analytics (and advertisement for the marketing consent) once the visitor has acted, and follows cookieyes_consent_update.
Klaro
Blocked until consent: a service named instantcampaign in your Klaro config; Klaro uses data-src for the address.
klaro.getManager().consents.instantcampaign once the visitor confirmed, and watches the manager for changes. Rename the service on the tag with data-ic-klaro-service="web-stats"; add a service instantcampaign-marketing when a marketing consent is required.
iubenda
Blocked until consent: purpose 4 (measurement); iubenda uses suppressedsrc for the address.
_iub.cs.api.getPreferences() and chains your _iub.csConfiguration.callback.onPreferenceExpressed (yours still runs): purpose 4 is measurement, purpose 5 the marketing consent.
IAB TCF v2.2 (any TCF consent manager)
Blocked until consent: not needed.
Let InstantCampaign read your consent manager: no code. The snippet listens through __tcfapi("addEventListener") and acts on tcloaded and useractioncomplete: purpose 8 for measurement, purposes 1 and 8 for recognition (plus 3 and 5 when a marketing consent is required), from the publisher consents or the purpose consents. Outside the GDPR (gdprApplies: false) both are on.
Google Consent Mode v2
Blocked until consent: not needed.
Let InstantCampaign read your consent manager: no code. The snippet follows your gtag("consent", "default" | "update", …) calls (and dataLayer.push(["consent", "update", …])): analytics_storage decides measurement and recognition; ad_user_data is also needed for recognition when a marketing consent is required. A default limited to some regions is ignored.
The consent banner on hosted pages
With Mode set to Persistent with consent, hosted landing pages (including your custom domain) show a small consent banner in your page’s theme and language, with two choices, Accept measurement and recognition and Only what is necessary, plus Manage. “Only what is necessary” keeps the anonymous measurement and refuses recognition. The banner stays hidden when the page has its own consent manager or your page code callsICTrack.consent() within a second of loading, and it never shows with Consent source set to My site code or in the builder. When you set a privacy policy URL, the banner links to it. The choice is remembered in the visitor’s browser (ic_consent_choice) for your workspace only: on our shared host pages.instantcampaign.ai it applies to your pages and never to another workspace’s, and on your custom domain to the whole domain. A Consent choices link at the bottom of the page lets them change it. With Mode set to Cookieless the banner never shows.
Recognising returning visitors
With Mode set to Persistent with consent, a visitor who agrees to recognition (through your consent manager, your code or our banner) gets a visitor id: a random value created by our server, never chosen by the browser and never shared between workspaces. It’s kept in a first-party cookie calledic_uid (and a copy in the browser’s storage, in case the cookie is cleared). On hosted landing pages our server sets the cookie for your pages only.
- What it does. The visitor’s visits are linked together. When they identify (from your email, a form, or your site code), all their earlier visits and anonymous events are added to the contact as history, not just today’s. Later visits are linked to the contact automatically.
- How long it lasts. The cookie is set once for 13 months and isn’t extended on later visits. Browsers decide too: about 13 months on Chrome and Firefox, but 7 days without a visit on Safari and Brave. On our side, a visitor id that isn’t seen for the number of days you chose (90 by default) is forgotten; the visits stay in your report, anonymous.
- Safeguards. If two visitor ids are linked to the same contact within 30 minutes (a shared computer, say), the second one isn’t merged. A visitor already linked to someone else is moved only when they submit a form or your site declares who they are, never by an email link alone. Every merge, skip and move is logged (with ids and counts only).
- Withdrawing. When the visitor withdraws recognition (your consent manager,
ICTrack.consent({ identity: false }), the Consent choices link on hosted pages,ICTrack.optOut(), or a Global Privacy Control / Do Not Track signal), the cookie and its copy are deleted and the visitor id is deleted on our side. What was already linked to the contact stays linked; withdrawal applies from then on. Erasing the contact removes their visitor ids, and they won’t be silently recognised again on their next visit. - In the report. Analytics → Website shows Identified across visits and a consent panel: how many visits granted recognition, refused it, carried a privacy signal or made no decision.
Website Traffic
Analytics → Website (the Overview tab) shows, for the selected period:- Visitors, Sessions, Pageviews, Time on page (time the page was actually visible) and Bounce rate, each compared with the previous period, plus how many visitors were Identified (known contacts).
- Visitor identity and consent: visits Identified across visits (through the visitor id) and how many visits granted recognition, refused it, carried a privacy signal or made no decision.
- Traffic over time, switchable Daily / Weekly / Monthly, with the same campaign and journey markers as the email charts.
- Tabbed breakdown cards:
- Top pages: Pages, Landing pages and Exits
- Top sources: Referrers, Sources, Channels and Channel groups
- Top campaigns:
utm_campaign, Mediums, Contents and Terms - Devices: Devices, Browsers and OS
- Countries: a Map or List view
- Traffic by day and hour: a heatmap in your workspace timezone.
Live
Analytics → Website → Live (the Live tab, or the “online now” badge) shows who’s on the site in the last 1, 5 or 30 minutes, refreshed every 10 seconds: current pages, where visitors came from, channels, campaigns, devices, countries, and an activity list of the most recently active visitors. Visitors are anonymous until they’re identified as a Known contact. On very busy sites, counts cover the most recent 1,000 sessions.Explore
Analytics → Website → Explore (the Explore tab) is for custom reports. Pick a preset from All reports, or click Create my own and Group by up to 4 dimensions. The table shows sessions, visitors, pageviews, average engaged time and bounce rate. Use Having at least to hide rows with few sessions. The report lives in the URL, so copy the link to share it. Export CSV downloads the table.Website Events
Analytics → Website → Events (the Events tab) lists custom events sent withICTrack.event(): Event Name, Contact (or Anonymous), Properties, Source and Time. Filter by event name.
Channels and attribution
Each visit is assigned a channel: direct, search, social, email, paid, AI assistant or referral. The channel comes from UTM tags first, then ad click ids (such asgclid or fbclid), then the referrer. To change how visits are classified, see Attribution rules. To see which channels, sources and rules go on to earn goals, open Conversion attribution.
AI assistants
Visits from AI assistants get their own channel, AI assistants, with the assistant as the source: ChatGPT, Perplexity, Gemini, Microsoft Copilot, Claude, DeepSeek, Grok, Meta AI, Mistral Le Chat, Duck.ai, You.com and Poe. A visit counts when it arrives with the assistant’s referrer (for examplechatgpt.com or perplexity.ai), with a utm_source naming it (ChatGPT adds utm_source=chatgpt.com to the links it cites), or with utm_medium set to ai, llm or ai-assistant on your own links. Many assistant apps send no referrer at all, so treat the count as a minimum: some of those visits show up as direct.
When someone signs up through one of your forms or landing pages during such a visit, the contact is marked with that visit’s channel. To build an “agent-sourced” segment, add the rule Acquisition channel equals AI assistants (see Segments). The channel is recorded once, when the contact is created, and never changes afterwards; contacts added before this existed have no acquisition channel.
If your workspace added starter attribution rules before AI assistants were covered, Add AI assistant rules on the Attribution rules page adds the missing ones. Then use Re-run over past visits to reclassify earlier visits.
Troubleshooting
No visits recorded yet
No visits recorded yet
Make sure the snippet is on the page and uses your full token. Check that the site’s hostname is in the token’s Allowed Domains, or that the list is empty. Also check that the testing browser hasn’t opted out (
ICTrack.isOptedOut() in the console; ICTrack.optIn() undoes it).I lost my token
I lost my token
Tokens are only shown once. Create a new token, update the snippet, then revoke the old one.
Email clicks aren't identifying visitors
Email clicks aren't identifying visitors
The link’s domain must be listed in a tracking token’s Allowed Domains, and Identify visitors who arrive from my emails must be on. A token with no allowed domains doesn’t add the id to any link. The tracking snippet must also be installed on the page the link opens. A browser with Global Privacy Control or Do Not Track on is never identified.
Events show as Anonymous, or a Website Event journey never starts
Events show as Anonymous, or a Website Event journey never starts
The visitor was not known when the event was recorded. Check the Contact column on the Events tab. A visitor becomes known by arriving from one of your emails, by submitting one of your forms, or, with Trust identity declared by your site code on, by your site calling
ICTrack.identify() with an existing contact’s email. A journey only starts for events recorded after that point. A browser that sends Global Privacy Control or Do Not Track is measured anonymously and never identified, so test without them.