To identify which companies visit your website and what they read, resolve each visit’s IP address to an organisation with Snitcher and keep the results in two Cargo models: one row per visiting company, and one per session with its pages and referrer. The site loads the tracker only after a visitor accepts it, and nothing identifies a named person.
The visitor-identification cookbook declares that setup for a site hosted on Cargo. This page covers what happens between a page view and a row, what the rows mean, what it costs and what it deliberately does not do.
Deploy it #
The site has to exist first, usually from website-building. Then, inside that Cargo project:
npm install -g @cargo-ai/cli
cargo-ai login --email you@company.com
cargo-ai cdk add cookbook/visitor-identification
cargo-ai cdk plan
cargo-ai cdk deploy
cdk add writes the two models to infra/visitor-identification/ and copies the site files (the consent gate, the loader and visitors.json) next to the procedure in .claude/skills/visitor-identification/. Your coding agent then wires them into the website app: render the gate from the layout, hand the app the tracker snippet as an env token, and point the banner at your privacy page.
How it works, end to end #
- A visitor accepts tracking. The site renders its own banner with equal “Accept tracking” and “Reject tracking” buttons. Before a choice, after a rejection, and under Global Privacy Control, the page makes no request to Snitcher at all.
- The site loads its own loader. It takes only the public profile ID from Snitcher’s snippet and loads the tracker with reviewed settings: consent required, and form, click, download, error and recording capture off. An unrecognised snippet fails the build.
- Snitcher resolves the visit. The IP address is matched to the organisation that owns it.
- Cargo syncs the rows.
website_visiting_companiesuses the SnitcherfetchOrganisationsextractor, andwebsite_visitor_sessionsusesfetchSessions. Both fetch incrementally on Cargo’s own interval, at most every 30 minutes, and refuse a cron.
The wiring is one deploy. Creating the companies model provisions a Snitcher workspace for your site URL and writes two values into the model’s config: _trackingScript, which the website app receives as NEXT_PUBLIC_SNITCHER_SNIPPET, and _workspaceUuid, which the sessions model reads. Both are CDK tokens, so they resolve in the same deploy that creates them.
Tracking runs only on the canonical origin of a site marked ready. The Cargo URL, previews and a draft site load nothing.
What comes back #
| Model | One row per | Fields |
|---|---|---|
website_visiting_companies | organisation resolved from a visit | name, website, industry, size, founded, address, profiles, first_seen, last_seen |
website_visitor_sessions | visit by an identified company | organisation_uuid, started_at, ended_at, referrer, device_type, location, views (each with url, visited_at, time_on_page) |
Join them on organisation_uuid = uuid to see which companies read your pricing page this week. Check the live column names with cargo-ai storage column list before you rely on a query; the extractor owns them.
Read the counts honestly. Visitors who reject send nothing, many addresses never resolve to an organisation (home broadband, mobile networks), and a shared office, VPN or coworking network resolves to whoever owns the address. A day with no identified company is a valid zero.
What it needs #
- A website on Cargo hosting with an HTTPS canonical URL, and
@cargo-ai/cdk1.0.98 or later. - The workspace’s default Snitcher connection, on Cargo’s credits. No Snitcher account or API key: the managed path provisions the tracker. A workspace on its own Snitcher key selects an existing workspace instead and provisions nothing.
- A privacy page you have reviewed that describes Snitcher, the purpose and the retention. The build fails while
privacyPolicyUrlis empty and tracking is on; the cookbook never writes legal text.
What it costs #
Each identified company is billed 3 credits once, when it first lands in the companies model. Sessions cost 0. That is the list price in the Snitcher integration’s definition; read it live with cargo-ai connection integration get snitcher before the first deploy. Spend follows your traffic and there is no built-in cap, so agree to it up front. Removing the companies model stops the billing.
What it will not do #
- Identify people. No identify call, no email capture, and no named person inferred from a visit. A row is a company.
- Load anything before consent. Snitcher’s own
waitForConsentstill records page views before consent, which is why the gate does not request the script until the visitor says yes. - Contact anyone. Nothing is sent. Acting on a visit (a score, an alert, an email) is your decision, and anything that does has to say it is about the company.
- Keep the history if the URL changes. A new
urlon the companies model provisions a new Snitcher workspace with a new tracker and an empty history.
Questions #
The cookbook is written for a site on Cargo hosting, because the snippet reaches the site as an app env token in the same deploy. The models themselves are ordinary Snitcher models; on another host you would load the tracker yourself, behind your own consent mechanism.
No. Call the loader from your CMP’s grant event and its deny path from revocation instead of rendering the gate, then re-test that nothing loads before a grant and after a withdrawal.
Not out of the box. The cookbook lists it as a variation: a segment over the companies model joined to your target list, with an alert on new rows. The alert has to say it is a company, because a visit says someone on that network read the page, not who.
Deploy it from the visitor-identification cookbook. To turn the visitors who do identify themselves into leads, see turn website visitors into routed, qualified leads.