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

# Authentication

> How to authenticate with the Zenstep REST API — snippet keys, session tokens, and which routes use which.

## Two authentication schemes

The Zenstep API uses two different authentication mechanisms depending on who is making the request:

| Scheme            | Used by                                                 | Routes                                                                         |
| ----------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Snippet key**   | Your snippet, Chrome Extension, backend event ingestion | `/api/v1/flows`, `/api/v1/events`, `/api/v1/heartbeat`, and most public routes |
| **Session token** | Dashboard (browser session)                             | `/api/v1/flows/[id]/analytics`, `/api/v1/flows/[id]/analytics/export.csv`      |

***

## Snippet key authentication

Your snippet key is a 32-character alphanumeric string visible on the **Install** page of the dashboard.

### Bearer token (recommended)

```bash theme={null}
curl https://app.getzenstep.com/api/v1/flows \
  -H "Authorization: Bearer YOUR_SNIPPET_KEY"
```

### Query parameter

For contexts where you cannot set request headers (such as `navigator.sendBeacon`):

```
GET /api/v1/heartbeat?key=YOUR_SNIPPET_KEY
```

<Note>
  The query parameter form exists specifically because `sendBeacon` cannot send
  custom headers. Use the `Authorization` header in all other cases.
</Note>

***

## Finding your snippet key

1. Log into the [Zenstep dashboard](https://app.getzenstep.com).
2. Go to **Install** in the left sidebar.
3. Your snippet key is shown in the install code snippet.

Your snippet key is safe to include in client-side code — it is read-only and scoped to your organisation. It cannot be used to write data (other than events sent from your own users' browsers).

***

## Session token authentication (dashboard API)

Analytics and export endpoints require a valid Supabase session token. These endpoints are called by the Zenstep dashboard itself — you do not need to use them from your own code.

If you're building a custom integration that reads analytics data, authenticate via the Supabase auth flow and pass the JWT as a Bearer token:

```bash theme={null}
curl https://app.getzenstep.com/api/v1/flows/FLOW_ID/analytics \
  -H "Authorization: Bearer YOUR_SUPABASE_JWT"
```

***

## Rate limits

See the [rate limits](/rest-api/rate-limits) page for limits per endpoint and how to handle `429` responses.

***

## Errors

All authentication errors return a `401 Unauthorized` response:

```json theme={null}
{
  "error": "Unauthorized"
}
```

Common causes:

* Missing `Authorization` header and no `?key=` query param
* Typo in snippet key
* Using a snippet key from a different organisation
* Session token expired (for session-authenticated routes)
