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

# Protect a landing page

> Make a PHP landing open through your campaign link and reject requests without a valid tracker key.

Landing protection helps prevent someone from opening your landing with just its plain URL. Metricanic adds a generated `lp_key` to the visitor's URL, and your landing checks that key before showing the page.

Use it for a **302 Redirect Mode** campaign when you control the landing's hosting. You need a server that runs PHP. A JavaScript check in the browser cannot protect HTML that has already been sent to the visitor.

## How it works

1. The visitor opens your campaign **Tracking link**.
2. Metricanic replaces `{lp_key}` in the landing URL with a generated key.
3. Your PHP page validates the key. A valid request opens the landing. A missing, changed, or expired key returns `404`.

This is an access check for the page, not bot detection or a login system. A valid URL can be reused in the same allowed period with the same User-Agent.

## 1. Prepare the PHP file

Create `metricanic-guard.php` beside your landing's `index.php`. Copy the code below into it. Open **Profile → Security → LP protection key**, click **Copy**, and replace `PASTE_YOUR_LP_PROTECTION_KEY` in that PHP file with the copied secret.

Keep the secret in PHP on your server. The public landing URL gets a generated key, never the secret from your profile.

<Accordion title="Copy the PHP protection file">
  ```php theme={null}
  <?php
  $secret = 'PASTE_YOUR_LP_PROTECTION_KEY';
  $key = $_GET['lp_key'] ?? '';
  $ttl = 600;
  header('Cache-Control: private, no-store');
  header('Referrer-Policy: no-referrer');

  if ($secret === '' || $secret === 'PASTE_YOUR_LP_PROTECTION_KEY') {
      http_response_code(500);
      exit;
  }
  if (!is_string($key) || !preg_match('/\A[0-9a-f]{5}([0-9]{5})[0-9a-f]{5}([0-9]{5})[0-9a-f]{54}\z/', $key, $parts)) {
      http_response_code(404);
      exit;
  }
  $timestamp = $parts[1] . $parts[2];
  $age = time() - (int) $timestamp;
  $hash = hash('sha256', $secret . $timestamp . ($_SERVER['HTTP_USER_AGENT'] ?? ''));
  $expected = substr($hash, 0, 5) . substr($timestamp, 0, 5)
      . substr($hash, 5, 5) . substr($timestamp, 5, 5) . substr($hash, 10);

  if ($age < -30 || $age > $ttl || !hash_equals($expected, $key)) {
      http_response_code(404);
      exit;
  }
  ```

  The file checks the tracker signature and allows keys up to 10 minutes old, with 30 seconds of future clock tolerance. These are settings of this example. Metricanic does not enforce that lifetime for your landing.
</Accordion>

## 2. Add one line before the page HTML

Put this at the very beginning of `index.php`, before any HTML, spaces, or other output:

```php theme={null}
<?php require __DIR__ . '/metricanic-guard.php'; ?>
```

If the landing is currently `index.html`, serve it as `index.php` on PHP hosting and update the landing URL if necessary. Remove the old public HTML copy after verifying the PHP page, otherwise it remains an unprotected way to open the same content.

If you use a CMS or page builder, its server must run this check before rendering the protected page. Pasting PHP into a browser-side HTML widget is not enough.

## 3. Add the key to the landing URL

Edit the landing in Metricanic and set its **URL** to:

```text theme={null}
https://landing.example.com/index.php?lp_key={lp_key}
```

Use `&lp_key={lp_key}` if the URL already has a query string. Select the landing in your campaign's rotator, save, and enter through **Tracking link**.

Disable shared HTML caching for this protected page and clear existing cached copies. Every request must reach the PHP check, including requests rejected earlier. Keep the original visitor User-Agent when a proxy forwards the request.

## Check that it works

| Test                                         | Expected result                     |
| -------------------------------------------- | ----------------------------------- |
| Open the landing URL without `lp_key`        | `404`.                              |
| Open the campaign Tracking link in a browser | The landing opens.                  |
| Change a character in the generated key      | `404`.                              |
| Reopen the URL after more than 10 minutes    | `404` with this example's lifetime. |

If every request fails, check the copied secret, PHP execution, server time, and User-Agent forwarding. If the bare page still opens, check for an old HTML copy or a cached response.

Do not enable this gate on the first page of **Direct Script Mode**. That page must open before its tracking script can register the visit. The account's protection secret is shared by its campaigns, so this check also does not restrict access to one particular campaign.
