Skip to content

Compass Web SDK: Consent & Identity

Consent and identity are tightly coupled in the Web SDK: no identifier is created, read, or persisted until consent is granted, and the identity the SDK resolves is what personalization is keyed on. This page covers both.

The SDK is CMP-agnostic. It does not parse IAB TCF / GPP / vendor strings itself; the host translates whatever its CMP returns into a single yes/no decision and passes it to setConsent.

Single gate

The Web SDK has one consent purpose — collect-for-personalization — expressed as a plain boolean. In v1 there is no separate analytics-only collection mode and no ephemeral-ID “soft-gate”: consent granted means collect with a stable identifier; not granted means collect nothing.

ArcCompass.setConsent(granted: boolean);

State machine

StateTriggerBehavior
unknownInitial; before setConsentEvents queue in memory (subject to the 500-event cap) and wait. Nothing is sent or persisted.
grantedsetConsent(true)Queue drains; events fire normally; future events flow live under a stable ID.
deniedsetConsent(false)Queue is dropped; any persistent ID is wiped; future events are dropped at track() time.

Consent can be revised at any time — calling setConsent again applies the new decision to subsequent events. Events already in flight when consent changes are not recalled.

Before setConsent is called, the SDK makes no network request and no persistent-storage write. Events captured pre-consent buffer in memory and flush on grant; on denial the buffer is dropped and any persistent ID is wiped.

Mapping a CMP to the gate

The host maps its CMP’s signal to the single boolean, e.g.:

// OneTrust
window.OptanonWrapper = function () {
const groups = OptanonActiveGroups.split(",");
ArcCompass.setConsent(groups.includes("C0004")); // personalization group
};

Identity & sessions

Identity is host-primary. The SDK uses the ID you set via setUserId() as-is, and generates its own anonymous ID only when you do not set one.

setUserId(userId) — the preferred path

Call this with the ID you already have for the visitor. It may be either:

  • a logged-in user ID, or
  • your own anonymous / visitor ID (many sites already assign one to signed-out visitors; if you have it, pass it).

A stable, host-managed ID is what makes personalization work across devices: the same ID on a phone and a laptop shares one history. Prefer it over the SDK’s per-device fallback whenever you can.

ArcCompass.setUserId("user-abc-123"); // logged-in or host visitor ID
ArcCompass.setUserId(null); // revert to the SDK anonymous fallback

The value is held in memory only — the SDK never writes it to a cookie or storage. You own its persistence. A blank or whitespace-only string is treated the same as null.

Anonymous fallback — only when you set no ID

When no host ID is set (and consent is granted), the SDK generates a UUID and writes it to:

  • a first-party cookie arccompass_aid with Domain=<cookieDomain>; Max-Age=63072000; SameSite=Lax (Secure is added on https origins), and
  • localStorage under the same key, as a mirror.

Read priority: cookie → localStorage → generate. If a value is found in one store but not the other, the SDK writes it back to repair the mirror. This fallback is per-device and less durable than a host-managed ID, but it makes a low-effort, out-of-the-box integration work with no identity wiring. A host-set ID always takes precedence over arccompass_aid.

cookieDomain is inferred from the current host by default; set it explicitly in init() for multi-subdomain sharing (e.g. .example.com).

getUserId() — keep the recommend read path coherent

The user_id the SDK puts on events must be the same raw value your recommend read-path query uses. The event collector and the recommendation read API pseudonymize user_id identically, so personalization silently breaks if the two paths send different raw values.

getUserId() returns the SDK’s resolved identifier so you can forward the identical value:

// When calling the recommend API from the browser:
const userId = ArcCompass.getUserId();
if (userId) {
const res = await fetch(`${RECOMMEND_URL}?user_id=${encodeURIComponent(userId)}`, {
headers: { "X-API-Key": deliveryToken },
});
// ...render recommendations
}

It returns:

  • the host-set ID when setUserId() has been called (regardless of consent — it is your value, never persisted by the SDK);
  • otherwise the persistent anonymous ID once consent is granted;
  • otherwise null — before consent (nothing may be read or written yet, and there is nothing to personalize) or before init().

Session ID

The SDK manages a session ID transparently:

  • generated on the first event and stored in sessionStorage (arccompass_sid) for the tab;
  • mirrored in a short-TTL cookie (arccompass_sid, plus arccompass_sls for the last-activity timestamp) so reloads stay within the same session;
  • slides on a 30-minute inactivity window — the next track() after the window expires mints a fresh session ID.

session_id is sent on every event and is used server-side to group a visit’s interactions into one personalization session. A per-call override via track(type, { sessionId }) is honored.

There is a single consent gate (see above). There is no ephemeral-ID soft-gate: before consent is granted the SDK creates and reads no persistent identifier, and on denial any persistent ID is wiped. Once granted, events carry the stable identity (host-set ID or the anonymous arccompass_aid) and the SDK-managed session ID.

Safari / ITP 7-day caveat

Both cookies set from JavaScript and localStorage entries are subject to Safari’s Intelligent Tracking Prevention 7-day cap on script-writeable storage. There is no client-only workaround, and this applies to the SDK’s arccompass_aid fallback. Returning visitors after seven days of no interaction may appear as new anonymous IDs, splitting their history. A stable host-managed ID passed to setUserId() (persisted server-side or in a first-party context you control) is the durable way to avoid this.

See also