# Install on WordPress

> The Survelium plugin for WordPress — install, page cache, WP-Cron and checks.

The plugin sees AI crawlers on the server and people arriving from assistants, and sends us the data from WP-Cron,
every five minutes.

**Requirements:** PHP 8.1 or newer, WordPress 6.0 or newer.

## Install

1. **Create a key** in Survelium → **Brand settings → Integrations → Create key**. It starts with `svk_` and is shown
   once; copy it.
2. **Download the plugin**: the file `survelium-agent-analytics-x.y.z.zip` from the
   [latest release](https://github.com/survelium/agent-analytics-wordpress/releases/latest). **Not** "Source code":
   that has no `vendor` folder and does not work.
3. In WordPress: **Plugins → Add New → Upload Plugin**, pick the zip and activate it.
4. **Settings → Survelium**: paste the key, save, then press **Send now**. "Sent." means we received the data.

The key can also live in `wp-config.php`, where it takes precedence over the settings page:

```php
define('SURVELIUM_INGEST_KEY', 'svk_...');
```

## Before you leave it running, check

- **The page cache.** Cached pages do not run PHP, so the plugin does not see the crawlers reading them.
  - **LiteSpeed** (the LiteSpeed Cache plugin, most shared hosting): handled. The plugin writes a block at the top of
    `.htaccess` that lets AI crawlers and visitors from assistants skip the cache. The status table shows "Active".
    The block is removed on deactivation.
  - **WP Rocket, W3 Total Cache, Cloudflare "cache everything", Varnish**: exclude AI crawler user agents from the
    cache by hand ([the list](https://survelium.com/docs/ai-traffic/crawlers.md#crawler-list)). Otherwise only uncached pages are reported.
- **WP-Cron runs.** If you set `DISABLE_WP_CRON`, call `wp-cron.php` from a real cron. The status table shows
  "overdue" when sending stops.
- **Behind Cloudflare or a proxy**, crawler IPs are the proxy's and cannot be
  [verified](https://survelium.com/docs/ai-traffic/crawlers.md#verification), unless you name the header carrying the real one:

  ```php
  define('SURVELIUM_IP_HEADER', 'HTTP_CF_CONNECTING_IP');
  ```

  Only set it if the proxy always sets that header.

## How it counts

- On every front-end page view (not admin, AJAX, REST or cron), after the page has gone out, the plugin checks for AI
  crawlers and assistants. Matches go to a table in your database (at most 20,000 rows).
- **The daily total**: people often get cached pages, so they are counted by a one-line script in the page footer,
  which only adds 1 (it sends nothing about the visitor). AI crawlers are added from PHP. Turn the script off and PHP
  counts everything, but cached pages are missing from the total.
- If it cannot reach us, it keeps the data and retries. A revoked key or a plan without AI traffic pauses sending
  without losing data; saving the settings resumes it.

## Settings

| Setting | Default | |
|---|---|---|
| Ingest key | — | Nothing is recorded while empty. |
| What to report | AI crawlers and visitors from AI assistants | Or AI crawlers only. |
| Page views | on | The footer script for the daily total. |
| Page cache | on | The LiteSpeed `.htaccess` block. |
| Ignored paths | `/wp-admin`, `/wp-login.php`, `/wp-cron.php`, `/xmlrpc.php`, `/wp-json` | Neither reported nor counted. |

## Check it works

- **Brand settings → Integrations** shows "Connected · last data …" a few minutes after **Send now**.
- Crawlers show up in **AI traffic → AI crawlers** as they come; on a small site that can take a day.

## Uninstall

**Plugins → Deactivate → Delete** drops the tables, the settings and the `.htaccess` block.
