The console uses the login cookie, server-side calls use an API key, and browser collect sends neither. API authentication details are on Authentication.
Transport
The console, the collect script, and /api/v1 use HTTPS as deployed. A successful login sets a cookie named wc_session: HttpOnly, SameSite Lax, 14 days. The Secure flag follows the deployment's cookie setting. When two-step verification is on, a correct password still does not set this cookie until the ticket and the code succeed. See Account & team.
Browser collect does not send this cookie. w.js posts events to /api/v1/pulse with sendBeacon or fetch and no credentials.
Keys
API keys are created at ConsoleConfigurationSettingsAPI keys. They start with wck_ and the full value is shown once. Send it in Authorization: Bearer. Scopes are a list such as track:write, stats:read, and privacy:write. * means every scope. A key can be bound to one project, or it can follow a user and then use that user's membership on each project.
A key is not a site key. The site key is on the website tag and may be public. A key can write data or read reports and belongs on a server. If you think one leaked, revoke it in the console and create another. Do not paste a full key into a support request. See Contact support.
Who can see what
Project roles decide which console pages open. See Account & team. The open API checks the key's scopes and project membership again. A missing scope is 403 / SCOPE_FORBIDDEN. A user who is not a member of the project is 403 / SITE_FORBIDDEN.
Reports can also be narrowed to channels, platforms, and hostnames, with properties hidden and a mask applied. The owner is not scoped this way.
The collector does not trust identity or tier claims from the browser. Tier, consent, bots, quota, and domain are decided again on the server. Obfuscation in the script does not replace that decision.
How each edge fails
The three edges are strict to different degrees, so one bad field does not become a permanent missing event or a dropped chat:
- Collect is lenient. A bad field is dropped and the good fields are kept. A reject still returns
202. An unattended page cannot see the error or retry on the spot. - Chat connections are in the middle. A broken structural field rejects that message. Over-long content is truncated and the connection stays up, so one status packet does not disconnect the visitor.
- Admin APIs are strict. A wrong type, an over-long string, or a value outside an enum fails the whole request with
400andcodeVALIDATION, plus a list of issues. Unknown fields are dropped. An extra key does not fail the request.
Rate limits are counted separately for keys, IPs, and sites. A full open-API bucket is 429. A full collect bucket is 202 and the hit is not stored. See Rate limits and API 401 / 403 / 429.
Audit
Adding, changing, and removing members, turning two-step verification on or off, using a recovery code, and changing privacy config are written to the audit log. ConsoleConfigurationSettingsAudit log can show it and export CSV, NDJSON, or JSON (at most 50,000 rows at a time). The groups are members and permissions, site and privacy, data governance, export, and login.
Addresses are not stored on events. The IP key used for rate limits is truncated or an HMAC, so it can stop a flood and cannot be looked up as a visit log. Geography keeps only the country or city field the policy allows. See Privacy & compliance.