# Install on WordPress

> Install the Kismet Telemetry WordPress plugin, a standalone, cache-safe plugin that implements the tracking contract with a settings screen, and verify it in six checks.


The Kismet Telemetry plugin implements the [contract](https://developers.kismet.travel/telemetry/contract.md) on WordPress. It is tracking only, no page elements, and it is built for full-page caches: the head bootstrap is identical for every visitor, and the per-visitor resolution happens in a never-cached call, so a cache can never freeze one visitor's id for everyone. WordPress 6.0 or later, PHP 7.4 or later.


**Contract 1.0 limit:** `externalListingId` can be emitted, but ingest-side resolution and generic conversions are Contract 1.1 additions. For property-level attribution today, arrange a registered serving-URL mapping or use a known Kismet property slug. Confirm backend support before relying on the 1.1 fields.


**Release status:** the standalone 1.1.1 ZIP is public. PHP, WordPress HTTP, browser-bootstrap and mixed WordPress/Next.js browser checks have passed locally. The visitor authority and published Next.js adapter were also verified against production. Confirm your actual consent manager, routing and cache configuration on staging before production installation.

## Before you start

Request from Kismet during onboarding: the collection slug and the collection's tracking key (`ctk_…`). The plugin stores the key encrypted at rest and never prints it into a page. Confirm your production and staging hostnames are on the collection's authorized domains.

## 1. Install the plugin

Download the [WordPress 1.1.1 ZIP](https://github.com/kismet-tech/kismet-telemetry-public/releases/download/telemetry-wordpress-v1.1.1/kismet-telemetry-1.1.1.zip), or review the [public plugin source](https://github.com/kismet-tech/kismet-telemetry-public/tree/main/packages/telemetry-wordpress). Upload the ZIP through WordPress: Plugins, Add New, Upload Plugin, then activate it. Validate on staging before production use.

## 2. Settings

Settings, Kismet Telemetry. Three groups.

**Connection.** Enabled; the collection slug; the tracking key (stored encrypted); an optional cookie domain override for sites whose registrable domain is deeper than the serving host (for example `book.example.com` sharing a session with `example.com`). Leave it empty for the dotted serving domain, `.example.com`.

**Consent.** How the plugin decides whether this visitor may carry a session:

- *Country default*: reads a Cloudflare country header and denies the EU, the UK, Switzerland and the EEA unless consent is signalled. Version 1.1.1 also denies missing, malformed and unknown country values. On Apache, Azure or any host without a trusted country header, cookies remain denied until your consent hook permits them. Earlier versions require an explicit consent hook to avoid allowing cookies when the header is absent.
- *Consent manager cookie*: the cookie name your consent manager writes and a pattern its value must match, for example `CookieConsent` and `statistics:true`. This is the mode for any site that already runs cookie consent, and the right one for a UK or EU site.
- *Always*: for sites outside consent jurisdictions.

Developers can replace the decision entirely with the `kismet_telemetry_should_set_cookies` filter. Consent gates the session, not the recording: every page is still recorded server-side, with a null session when no session was allowed.

**Route profile.** Which URLs are what, so the server plane can light the funnel stages with no client code: the property page pattern (a regular expression whose first capture group is the listing identifier, sent as your own `externalListingId` or as a Kismet slug), the results pages (one path per line, `*` for a prefix), the checkout path, and the stay parameter names on it. The `kismet_telemetry_property`, `kismet_telemetry_is_search`, `kismet_telemetry_intent` and `kismet_telemetry_is_agent_surface` filters override each decision in code.

## Returning-visitor recognition

After Kismet enables your collection, add this to server configuration such as `wp-config.php`:

```php
define('KISMET_TELEMETRY_VISITOR_RECOGNITION', true);
```

Use the consent-manager cookie settings or `kismet_telemetry_should_set_cookies` filter. Geography alone does not enable visitor recognition. The existing AJAX anchor performs the bounded authority request and sets `_kid_vid`; no separate plugin or custom visitor-matching code is required. See the [returning-visitor guide](https://developers.kismet.travel/telemetry/visitor-recognition.md) for recovery and consent checks.

## 3. The checkout call

From the code that knows the booking succeeded, once:

```php
kismet_telemetry_booking_bridge([
    'kidSid'           => $_COOKIE['_kid_sid'] ?? null,
    'confirmationCode' => $confirmation_code,
    'bookingEngine'    => 'custom',
    'domain'           => 'example.co.uk',
]);
```

`kismet_telemetry_quote_capture()` records a quote the guest saw, for the fallback match on property and dates. Both are bounded, never throw, and must not affect the booking.

## What the plugin does on every page

- **Head bootstrap** (`wp_head`, priority 0): a site-constant script, safe to cache. Every bootstrap checks the never-cached `kismet_telemetry_anchor` endpoint, including when a session cookie already exists. It rechecks consent before seeding the session and loading the browser tracker. On anchor failure or the 1.5-second timeout, identity is suppressed and the browser tracker is withheld.
- **Resolution**: threaded id, cookie, suppressed (bots, no consent), else a local mint with an after-response reconcile carrying the visitor's signals, click ids and landing URL, which is the first-touch capture paid attribution depends on.
- **Cookies**: `_kid_sid` for 90 days; optional `_kid_vid` for up to 400 days after explicit consent and collection enablement. Browser policies and deletion may shorten the lifetime. Both cookies are set on the dotted serving domain, `SameSite=Lax`, `Secure` on HTTPS, never `HttpOnly`.
- **Server-plane beacon**: one event per PHP-served front-end request, bots included, with the route profile deciding `view`, `property_view`, `cta_click` or `fetch`. A request served entirely from a full-page cache never reaches PHP and is invisible here; that shows up as a coverage gap in your reports, not as zero traffic.

The [overview](https://developers.kismet.travel/telemetry.md#how-it-works) walks through the six steps; the [contract](https://developers.kismet.travel/telemetry/contract.md) specifies them.

## Kismet Elements on the same site

When the Kismet Elements plugin is active, Telemetry owns tracking: Elements' anchor bootstrap is unhooked, its beacon is switched off, and its collection slug and key are inherited when the fields here are empty. No change to Elements is needed.

## Pairing with a Next.js app under a path

A common shape: WordPress serves the root and a Next.js app serves `/stays/` with its own checkout. Install this plugin at the root and [`@kismet-tech/telemetry-next`](https://developers.kismet.travel/telemetry/nextjs.md) in the app, both with the same collection and key. Both set the cookie on `.example.co.uk`, so whichever surface the visitor lands on first mints the id and the other adopts it; one session survives the boundary in both directions. Make the booking-bridge call from the surface that owns the checkout.

## Staging and lab overrides

In `wp-config.php`: `KISMET_TELEMETRY_RESOLVE_URL`, `KISMET_TELEMETRY_TRACK_URL`, `KISMET_TELEMETRY_API_ORIGIN`, `KISMET_TELEMETRY_KJS_URL`.

## Verify

1. Load a page in a fresh browser. Expect a `_kid_sid` cookie on the dotted domain and `window.Kismet._kidSid` equal to it.
2. Reload with consent retained. The same session is adopted; enabled visitor recognition may set or refresh `_kid_vid`.
3. `curl -A GPTBot https://your-host/some-page`: no `Set-Cookie`; Kismet records the fetch with the bot classified and no session.
4. `curl https://your-host/llms.txt`: recorded as a fetch with no session.
5. From a consent jurisdiction without consent: no cookie, page still recorded.
6. If using the booking bridge, complete a staging test booking and verify its successful response and session join.
7. With visitor recognition enabled, restart the browser, remove only `_kid_sid`, then cross to Next.js and back. Expect the same `_kid_vid`; Kismet can verify the new session links. Withdraw consent and confirm both cookies are removed on the next anchor request.

If the site is on WP Engine or another host with a full-page cache, check 1 in a fresh browser is the one that matters: the cookie must come from the anchor endpoint, not from a cached page.

## Pin the browser tracker

To review browser code before it changes on your site, configure the [pinned browser tracker](https://developers.kismet.travel/telemetry/pinned-browser-tracker.md). Pinning the npm package or WordPress plugin alone does not pin the default `k.js` URL. The pinned release works with version 1.1.0 and preserves your existing consent and returning-visitor configuration.

## Connect an existing consent banner

Follow the [consent integration guide](https://developers.kismet.travel/telemetry/consent.md) to map your saved banner choice to both server adapters and browser tracker 1.2.0. Kismet can prepare the configuration if you share your CMP, consent-cookie format and saved-choice callback.
