Status — read first
AI-assisted best-effort draft · not legal advice · not lawyer-reviewed.
This document was drafted with AI assistance as a best-effort starting point. No licensed attorney has reviewed, approved, or certified it, and it is not safe to rely on as a binding or compliant document. A qualified attorney in each operating jurisdiction must review and finish it before it is published or enforced. Nothing here claims an audit, certification, corporate registration, or executed contract that has actually happened.
This inventory has to be verified against the running app before it is published. Engineering re-greps document.cookie, localStorage, and sessionStorage and confirms the table; counsel then classifies each row for ePrivacy/PECR consent. Keep this as the engineering-maintained inventory and have the public page render from it, so the two cannot drift apart again.
Who sets these, and where
This inventory covers the storage set by Vettika, a service operated by Nexprove across both domains it operates — vettika.com and airecruiter.nexprove.com. The same first-party storage is used on both; none of it is shared across unrelated sites. Candidate-facing flows are intended to be analytics-free (see below).
The correction that matters most
Earlier copy said a session cookie was “reserved for if and when we ship sign-in” and omitted the actual login cookies. That was wrong. Better Auth with Google sign-in has been live since Session 3, and recruiters are logging in right now. The auth cookies below are real and set today.
Inventory (verify against the running app before publish)
| Storage key | Type | Set by | Purpose | Category | Retention |
|---|---|---|---|---|---|
| better-auth.session_token | Cookie (HttpOnly, Secure, SameSite=Lax) | Better Auth | Recruiter session — live today | Strictly necessary | Session + ~30 days |
| Better Auth CSRF cookie | Cookie | Better Auth | CSRF protection — live today | Strictly necessary | Session |
| Cookie-consent choice | localStorage | consent store | Records the user's own consent choice | Strictly necessary | Until cleared |
| aii_consent | Cookie (first-party, Secure, SameSite=Lax) | consent store | Server-readable mirror of the choice above, so the consent can be enforced in middleware | Strictly necessary | 12 months |
| aii_did | Cookie (first-party, HttpOnly, Secure, SameSite=Lax) | account security | Random per-browser marker with no identity in it, so we can tell a sign-in from a browser you have used before from a sign-in from one we have never seen, and email you about the second | Strictly necessary (security / fraud prevention) | 400 days |
| theme | localStorage | next-themes | Only written when you pick a theme yourself; absent until then, when the site follows your browser setting | Strictly necessary (user-initiated preference) | Until cleared |
| Candidate consent mirror | localStorage | candidate consent store | Local copy of submitted candidate consent, to resume across page loads | Strictly necessary | Until cleared |
| Campaign draft | localStorage | campaign wizard | In-progress campaign draft (recruiter) | Functional | Until cleared / submit |
| Vercel Analytics ID | Cookie | @vercel/analytics | First-party traffic analytics | Analytics — consent-dependent | Short rolling |
| Speed Insights (no storage) | No cookie, no localStorage | @vercel/speed-insights | Core Web Vitals (LCP, INP, CLS) per route, to find slow pages | Analytics — consent-dependent | Not stored on your device |
| aii_attr, aii_anon | Cookie (HttpOnly, Secure, SameSite=Lax) | marketing attribution | Which link or campaign brought you here; anonymous id joining a demo to a later signup | Marketing — consent-dependent | 90 days |
Storage-key prefixes (aircruiter:, etc.) are historical from the old brand and should be checked against what the current build actually writes. None of these cross sites.
How your choice is enforced
Analytics is live and it is opt-in. Vercel Analytics and Vercel Speed Insights load only after you turn Analytics on, on marketing and signed-in pages only; candidate-facing pages never load either one whatever you choose. There is no Google Analytics, no pixel, and no third-party tag on any page.
Speed Insights is listed even though it stores nothing on your device. It measures how fast a page loaded and responded and sends that back with the route name — no cookie, no identifier, nothing that follows you between visits. Being cookieless is not by itself a reason to leave something out of a consent prompt, so it sits under the same Analytics toggle as everything else and is off until you turn that on.
The attribution cookies are consent-dependent, and the gate is real. aii_attr (which link brought you here) and aii_anon (an anonymous id joining a demo to a later signup) are classified as marketing, not strictly necessary — first-party does not by itself make a cookie exempt under ePrivacy/PECR. They are written only where the Marketing toggle allows it:
- If you have made a choice, it is honoured everywhere, in both directions. Turning Marketing off also deletes any attribution already stored — withdrawal is retroactive, not just forward-looking.
- If you have not chosen yet, nothing is written for visitors in the EEA, the UK or Switzerland, where consent must come first. Elsewhere, first-touch attribution may be set on arrival and is removed as soon as you decline.
Your choice is kept in localStorage and mirrored into the first-party aii_consent cookie. The mirror exists for one reason: the code that sets tracking cookies runs at the edge, where localStorage cannot be read, so a preference stored only in the browser could not actually stop anything. That was the defect this section used to describe as an open question.
You can change your mind at any time, and the prompt is not a dark pattern — rejecting is a single click, in the same place and the same size as accepting.
What we do not set
No Google Analytics, Meta Pixel, or TikTok Pixel. No third-party advertising cookies. No fingerprinting libraries. No session-replay tools. (Verify this remains true at each release.)
Candidate pages
The candidate flows (apply, interview, feedback) should be analytics-free. This is to be enforced at the route boundary, not just by a consent-banner default being off. Where the enforcement is still a default rather than a hard guard, we do not describe it publicly as a guarantee.
How to control cookies
You have several levers:
- Strictly-necessary storage (session and CSRF cookies, your consent choice) cannot be switched off without breaking sign-in — clearing it signs you out.
- Functional and analytics storage can be declined; where a consent banner is in force, your choice is recorded and honored.
- Browser controls let you block or delete cookies and site data for vettika.com and airecruiter.nexprove.com at any time; doing so may sign you out or reset preferences.
Audit cadence
- Before each release: grep for
document.cookie,localStorage.setItem,sessionStorage.setItemand reconcile this table with reality. - Quarterly: counsel reviews the classifications.