> ## 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

> Track AI crawlers on Laravel, Drupal, Craft or a custom PHP site with one config line.

`snowseo-beacon.php` is a single file with no dependencies. It loads before your application, decides in a few microseconds whether the request is worth reporting, and gets out of the way. Your application code is not touched.

Requires PHP 7.4 or later.

<Info>
  On WordPress, use the [SnowSEO plugin](/docs/beacon/install/wordpress) instead. It does the same job and adds settings, buffering and a page-cache coverage check.
</Info>

***

## Setup

<Steps>
  <Step title="Put the file on your server">
    Download `snowseo-beacon.php` and place it somewhere outside your web root:

    ```bash theme={null}
    /var/www/snowseo-beacon.php
    ```
  </Step>

  <Step title="Load it for every request">
    Add one line to `php.ini`, your PHP-FPM pool config, or a `.htaccess`:

    ```ini php.ini theme={null}
    auto_prepend_file = /var/www/snowseo-beacon.php
    ```

    ```apache .htaccess theme={null}
    php_value auto_prepend_file /var/www/snowseo-beacon.php
    ```

    Then reload PHP-FPM or Apache.
  </Step>

  <Step title="Set your site key">
    ```bash theme={null}
    SNOWSEO_BEACON_KEY=sb_live_...
    ```

    Or, if setting environment variables is awkward, define it in a file loaded before the prepend:

    ```php theme={null}
    define( 'SNOWSEO_BEACON_KEY', 'sb_live_...' );
    ```

    Generate the key under **Settings → Integrations → Beacon** in the SnowSEO dashboard.
  </Step>
</Steps>

Verify with a crawler user agent:

```bash theme={null}
curl -A "GPTBot/1.2" https://example.com/
```

***

## Configuration

All optional, read from a constant first and then the environment.

| Setting                   | Default                   | Purpose                                                                           |
| ------------------------- | ------------------------- | --------------------------------------------------------------------------------- |
| `SNOWSEO_BEACON_KEY`      | —                         | Required. Your site key.                                                          |
| `SNOWSEO_BEACON_ENDPOINT` | `https://api.snowseo.com` | Point at a self-hosted or tunnelled API. A bare origin is fine.                   |
| `SNOWSEO_BEACON_HOST`     | Request host              | Override when one origin serves a brand under several hostnames.                  |
| `SNOWSEO_BEACON_SEND_IP`  | `1`                       | Set to `0` to stop sending IP addresses. Crawlers can then no longer be verified. |
| `SNOWSEO_BEACON_EXCLUDE`  | See below                 | Comma-separated path prefixes to ignore.                                          |
| `SNOWSEO_BEACON_DISABLE`  | —                         | Set to any truthy value to turn everything off.                                   |

Default exclusions: `/wp-admin`, `/wp-json`, `/wp-login.php`, `/xmlrpc.php`, `/api/`, `/graphql`, `/_next/`, `/assets/`, `/static/`, `/build/`, `/health`, `/healthz`, `/status`, `/favicon.ico`, `/robots.txt`.

Setting `SNOWSEO_BEACON_EXCLUDE` replaces that list rather than adding to it.

***

## What it does per request

1. Exits immediately for CLI, non-`GET`/`HEAD` requests, and anything from a browser. This is the overwhelming majority of traffic and it costs a handful of array lookups.
2. For a request that asked for Markdown or carried no `Sec-Fetch-*` header, checks the path is a page route and not excluded.
3. Registers a shutdown function, so nothing happens until your response is already produced.
4. Calls `fastcgi_finish_request()` where available, so the visitor's connection is closed before the report is sent. On PHP-FPM and LiteSpeed this means zero added latency.
5. POSTs the hit with a 2-second timeout, swallowing every error.

A SnowSEO outage cannot slow or break your site. The worst case is one 2-second timeout on a crawler's request, after that crawler already has its response.

***

## High-traffic sites

The standalone client sends one request per reportable hit, because plain PHP has nowhere to keep a buffer between requests. Since ordinary visitor traffic is filtered out before this point, that is crawler-only volume and fine for almost every site.

Above roughly ten crawler hits per second you will want batching. Either front the site with a Node runtime and use [`@snowseo/beacon`](/docs/beacon/install/fetch-frameworks), or get in touch about the APCu-buffered variant.
