Skip to main content

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.

Two authentication schemes

The Zenstep API uses two different authentication mechanisms depending on who is making the request:
SchemeUsed byRoutes
Snippet keyYour snippet, Chrome Extension, backend event ingestion/api/v1/flows, /api/v1/events, /api/v1/heartbeat, and most public routes
Session tokenDashboard (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.
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
The query parameter form exists specifically because sendBeacon cannot send custom headers. Use the Authorization header in all other cases.

Finding your snippet key

  1. Log into the Zenstep dashboard.
  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:
curl https://app.getzenstep.com/api/v1/flows/FLOW_ID/analytics \
  -H "Authorization: Bearer YOUR_SUPABASE_JWT"

Rate limits

See the rate limits page for limits per endpoint and how to handle 429 responses.

Errors

All authentication errors return a 401 Unauthorized response:
{
  "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)