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

# Authentication

> Authenticate Tracking API requests with your storefront access token, passed as a header or as a query parameter for sendBeacon compatibility.

The Tracking API uses the same storefront access token as the rest of the Layers Storefront API. The token identifies which store the events belong to and which pipelines should receive them.

## Token sources

The worker accepts the token from **either** of these locations, in this order:

1. `X-Storefront-Access-Token` header
2. `token` query string parameter

If both are present, the header wins. If neither is present, the request returns `401 Unauthenticated`.

### Header (preferred)

Use the header form whenever you control request headers — typically server-to-server calls, or browser `fetch` calls where you don't need `sendBeacon`.

```http theme={null}
POST /beacon HTTP/1.1
Host: cl.uselayers.com
Content-Type: application/json
Accept: application/json
X-Storefront-Access-Token: shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

### Query parameter (for `navigator.sendBeacon`)

[`navigator.sendBeacon`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) does not let you set custom headers. Pass the token in the query string instead:

```js theme={null}
navigator.sendBeacon(
  `https://cl.uselayers.com/beacon?token=${encodeURIComponent(STOREFRONT_TOKEN)}`,
  new Blob([JSON.stringify({ events })], { type: 'application/json' })
);
```

<Warning>
  The token will appear in the URL and may be logged by intermediate proxies or browser history. The storefront token is a **public, scoped** credential intended to be embedded in storefront JavaScript — it has write access only to event ingestion and read access to storefront endpoints, never to admin operations. Treat it the same way you'd treat a Shopify Storefront API access token.
</Warning>

## Errors

| Status | Body                             | Meaning                                                                                          |
| ------ | -------------------------------- | ------------------------------------------------------------------------------------------------ |
| `401`  | `{ "error": "Unauthenticated" }` | Token missing or not recognized for any store.                                                   |
| `422`  | `{ "errors": [ "..." ] }`        | Request body failed top-level validation (e.g., `events` is missing, empty, or longer than 100). |

Per-event validation errors do not return `422`. Invalid events inside a valid batch are skipped silently so the rest of the batch still ingests.

## CORS

The endpoint reflects the request `Origin` header and allows credentials, so it works from any browser origin you've authorized via your storefront token's allowed domains.
