Authentication
Latch uses four auth modes.
1. API keys
Section titled “1. API keys”Send API keys in the X-API-Key header.
| Key type | Prefix | Use case |
|---|---|---|
| Publishable | pk_ | browser access checks, events, and customer auth |
| Secret | sk_ | server-side subscription lookup, checkout, and portal |
Publishable keys
Section titled “Publishable keys”Publishable keys are safe in browser code and can call:
GET /api/v1/access/checkPOST /api/v1/eventsPOST /api/v1/auth/customers/registerPOST /api/v1/auth/customers/loginPOST /api/v1/auth/customers/refreshPOST /api/v1/auth/customers/logoutGET /api/v1/auth/customers/me
Secret keys
Section titled “Secret keys”Secret keys must stay server-side and can call:
GET /api/v1/subscriptions/mePOST /api/v1/subscriptions/checkoutPOST /api/v1/subscriptions/cancelPOST /api/v1/subscriptions/portal
Customer auth routes
Section titled “Customer auth routes”Customer auth routes accept either publishable or secret keys:
POST /api/v1/auth/customers/registerPOST /api/v1/auth/customers/loginPOST /api/v1/auth/customers/refreshPOST /api/v1/auth/customers/logoutGET /api/v1/auth/customers/me
2. Dashboard admin sessions
Section titled “2. Dashboard admin sessions”Dashboard management routes use an authenticated admin session cookie.
That includes:
- products and prices
- paywalls
- customers
- segments
- API keys
- stats
- Stripe settings
3. Stripe webhook signatures
Section titled “3. Stripe webhook signatures”POST /api/v1/webhooks/stripe does not use API keys. It validates Stripe signatures instead.
4. Customer authentication (JWT)
Section titled “4. Customer authentication (JWT)”Customer auth is optional. When enabled, customers register and log in with email and password. The API returns:
- a JWT access token (15-minute expiry) for fast, stateless identity verification
- an opaque refresh token (30-day expiry) for obtaining new access tokens
How it works
Section titled “How it works”- Call
POST /api/v1/auth/customers/registeror/loginwith any API key (pk_orsk_) - The API returns
accessToken,refreshToken,expiresAt, andcustomer - Store both tokens on the client (the SDK handles this automatically via
localStorage) - Pass the access token as
Authorization: Bearer <token>with access checks - When the access token expires, exchange the refresh token for a new pair via
/refresh
Registration example
Section titled “Registration example”curl -X POST https://your-api/api/v1/auth/customers/register \ -H "X-API-Key: pk_..." \ -H "Content-Type: application/json" \{ "accessToken": "eyJhbGciOiJIUzI1NiIs...", "refreshToken": "a1b2c3d4e5f6...", "expiresAt": 1712345678, "customer": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Jane" }}Login example
Section titled “Login example”curl -X POST https://your-api/api/v1/auth/customers/login \ -H "X-API-Key: pk_..." \ -H "Content-Type: application/json" \Access check with verified identity
Section titled “Access check with verified identity”curl https://your-api/api/v1/access/check?url=https://example.com/premium \ -H "X-API-Key: pk_..." \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."When a valid JWT is present, the verified customer ID from the token takes precedence over the userId query parameter.
Token refresh
Section titled “Token refresh”Refresh tokens are rotated on use. Each call to /refresh invalidates the old refresh token and returns a new pair.
curl -X POST https://your-api/api/v1/auth/customers/refresh \ -H "X-API-Key: pk_..." \ -H "Content-Type: application/json" \ -d '{"refreshToken": "a1b2c3d4e5f6..."}'Logout
Section titled “Logout”curl -X POST https://your-api/api/v1/auth/customers/logout \ -H "X-API-Key: pk_..." \ -H "Content-Type: application/json" \ -d '{"refreshToken": "a1b2c3d4e5f6..."}'Rate limiting
Section titled “Rate limiting”Requests are rate-limited per identity.
| Endpoint group | Limit |
|---|---|
| Access checks | 1,000 requests/minute |
| Events | 200 requests/minute |
| All other endpoints | 200 requests/minute |
Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
Interactive API explorer
Section titled “Interactive API explorer”The API serves interactive docs at /docs.