> ## Documentation Index
> Fetch the complete documentation index at: https://snowseo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP and WordPress reference

> Every constant the standalone PHP client reads, and every filter the WordPress plugin exposes.

The PHP client installs with one `auto_prepend_file` line and reads its whole configuration from constants or environment variables. See [PHP install](/docs/beacon/install/php) to get it running, and [WordPress](/docs/beacon/install/wordpress) for the plugin.

Each setting can be a `define()` or an environment variable of the same name. A constant wins if both are set.

***

## Constants

| Constant                  | Default          |                                                                                                      |
| ------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| `SNOWSEO_BEACON_KEY`      |                  | **Required.** Your site key.                                                                         |
| `SNOWSEO_BEACON_ENDPOINT` | SnowSEO          | Where hits go. Point it at [your own collector](/docs/beacon/self-hosting/reference-server) to self-host. |
| `SNOWSEO_BEACON_HOST`     | from the request | Override the host hits are attributed to. Useful behind a proxy that rewrites `Host`.                |
| `SNOWSEO_BEACON_SEND_IP`  | `1`              | Set to `0` to never send the source address. Costs you verification: every hit becomes `unverified`. |
| `SNOWSEO_BEACON_EXCLUDE`  | see below        | Comma-separated path prefixes to skip. Replaces the defaults entirely.                               |
| `SNOWSEO_BEACON_SPOOL`    | off              | Writable directory for undelivered hits. Strongly recommended.                                       |
| `SNOWSEO_BEACON_DISABLE`  |                  | Truthy value turns the client off without uninstalling it.                                           |

### The default exclusions

Set `SNOWSEO_BEACON_EXCLUDE` and you replace this list rather than adding to it, so repeat anything you still want skipped:

```
/wp-admin, /wp-json, /wp-login.php, /xmlrpc.php,
/api/, /graphql, /_next/, /assets/, /static/, /build/
```

### Spooling

Without `SNOWSEO_BEACON_SPOOL`, a hit that cannot be delivered is lost. With it, hits are written one JSON line at a time and drained on a later request.

A network failure, a 429 or a 5xx opens a **5-minute circuit breaker**, so a dead endpoint costs one attempt per five minutes rather than a full timeout on every page view. Spooled hits are kept for 23 hours, and the file is capped at 1 MB.

<Note>
  `SNOWSEO_BEACON_HANDLED` is set by the client itself, not by you. It tells the WordPress plugin - which loads far later, if at all - that this request already has an owner, so the two cannot double-count.
</Note>

***

## WordPress filters

| Filter                          | Signature       |                                                                                             |
| ------------------------------- | --------------- | ------------------------------------------------------------------------------------------- |
| `snowseo_beacon_enabled`        | `bool $enabled` | Force tracking on or off in code.                                                           |
| `snowseo_beacon_should_record`  | `bool $record`  | Decide per request. Runs after the built-in pre-filter, so you are narrowing, not widening. |
| `snowseo_beacon_finish_request` | `bool $allowed` | Whether the connection is closed before flushing. Defaults to off under `WP_DEBUG`.         |
| `snowseo_api_url`               | `string $url`   | The SnowSEO API base, for the whole plugin.                                                 |

```php theme={null}
// Never report the staging subdomain.
add_filter('snowseo_beacon_enabled', function ($enabled) {
    return $enabled && 'staging.example.com' !== $_SERVER['HTTP_HOST'];
});
```

```php theme={null}
// Skip a noisy route the default exclusions do not cover.
add_filter('snowseo_beacon_should_record', function ($record) {
    return $record && 0 !== strpos($_SERVER['REQUEST_URI'], '/feed/');
});
```

`snowseo_beacon_should_record` exists so you can drop traffic without waiting for a plugin release. It cannot make the client record something the pre-filter already rejected.

***

## What the client never does

* **No classification.** It sends the raw `User-Agent` and lets the server decide. A client that graded its own traffic could simply assert a verdict.
* **No dependencies.** Adding one would mean shipping an autoloader the WordPress build does not produce.
* **Nothing above PHP 7.4.** No union types, no `match`, no constructor promotion, no nullsafe operator.
* **Nothing for ordinary visitors.** The pre-filter runs before anything else, so a normal page view costs no measurable time and sends no request.

***

## Where the source lives

The PHP client is built from a single core shared with the WordPress plugin, in the [WordPress plugin repository](https://github.com/Snow-SEO/snowseo-wordpress-plugin). The JavaScript client and the ingest server are in [Snow-SEO/beacon](https://github.com/Snow-SEO/beacon).
