> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pivolio.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pivolio.com/_mcp/server.

# First-party domains

By default the SDK talks to `https://api.pivolio.com`. That hostname is a
third-party domain to your visitors, and two things happen to third-party
domains: ad-blocker filter lists eventually add them, and Safari's Intelligent
Tracking Prevention treats their cookies as third-party.

Pointing a subdomain you own — say `track.yourcompany.com` — at the collector
fixes both. Requests are same-site, blocklists have nothing generic to match on,
and cookies set on that hostname are first-party.

## Set it up

#### Add the domain in the dashboard

Add the hostname you want to use. Pick a subdomain of your main site —
`track.yourcompany.com` works, an unrelated domain you also own does not,
because to the browser it would still be third-party.

Pivolio gives you a **target hostname** to point at.

#### Create the CNAME record

In your DNS provider, add one record:

* **Type** — `CNAME`
* **Name** — your hostname (`track`, or `track.yourcompany.com` depending on
  how your provider asks for it)
* **Value** — the target Pivolio showed you

Nothing else — no `TXT` record, no `A` record, no certificate upload.

#### Wait for verification

Pivolio polls the record. Once it resolves, TLS is issued automatically
through Cloudflare — there is no CSR to generate and no certificate to
upload or renew.

Propagation is usually minutes, but DNS TTLs can stretch it to a few hours.

#### Point the SDK at it

Change `apiUrl` and redeploy:

```ts
import { init } from '@pivolio/browser';

init({
  writeKey: 'wk_live_xxxxxxxxxxxx',
  apiUrl: 'https://track.yourcompany.com',
});
```

Nothing else changes — the same endpoints, the same write key, the same
event bodies.

## Statuses

The domain shows one of four states:

* **`pending`** — the record was added in Pivolio but DNS hasn't resolved to the
  target yet. Normal for the first few minutes.
* **`verified`** — the CNAME resolves correctly; the certificate is being
  issued.
* **`active`** — TLS is live and the hostname is serving traffic. Only now is it
  safe to move `apiUrl` over.
* **`error`** — verification or issuance failed. The usual cause is a CNAME
  pointing somewhere other than the target, or a conflicting `A`/`AAAA` record
  on the same name.

> **Warning**
>
> Don't switch `apiUrl` before the domain reads **active**. Requests to a hostname
> without a valid certificate fail at the TLS handshake, and the SDK will queue
> and eventually drop those events.

## Cookies across subdomains

A first-party domain pairs well with `cookieDomain`. Setting it to the
registrable domain lets one visitor keep the same anonymous ID across
`www.yourcompany.com`, `shop.yourcompany.com`, and anything else you run:

```ts
init({
  writeKey: 'wk_live_xxxxxxxxxxxx',
  apiUrl: 'https://track.yourcompany.com',
  cookieDomain: '.yourcompany.com',
});
```

> **Note**
>
> A first-party domain reduces blocking; it doesn't eliminate it. Some blocklists
> match on request paths and payload shapes too. What it reliably buys you is
> cookie lifetime — the anonymous ID stops resetting every seven days on Safari,
> which is usually the larger of the two losses.

## What doesn't change

Your write key, the endpoint paths, and the event schema are identical. You can
run both hostnames at once during a migration — events from
`api.pivolio.com` and `track.yourcompany.com` land in the same workspace and
resolve against the same identity graph, so there's no cutover risk beyond the
usual deploy.