Authentication
The LVNG API supports two authentication methods: JWT tokens (via Supabase) for user sessions, per-user API keys (lvng_sk_*) for programmatic access and Claude Code, and service API keys for backend services. All methods resolve to a tenant-scoped request context that isolates all data operations.
Overview
Authorization: Bearer <jwt>Browser apps, user sessionsAuthorization: Bearer YOUR_API_KEYClaude Code, SDKs, scripts, CI/CDJWT Tokens
LVNG uses Supabase-issued JWTs as the primary authentication method for user sessions. Tokens are validated server-side using the jsonwebtoken library against the JWT_SECRET environment variable.
Token Claims
The JWT payload contains the following claims:
{
"userId": "uuid-of-the-user",
"email": "user@example.com",
"role": "admin",
"organizationId": "org-uuid",
"iat": 1710864000,
"exp": 1710867600
}Token Lifetime
Request Example
curl -X GET https://api.lvng.ai/api/v2/channels \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json"How It Works
- The user signs in via Supabase Auth (email/password, OAuth, or magic link).
- Supabase returns an access token (JWT) and a refresh token.
- Your frontend sends the access token in the
Authorizationheader with every request. - The LVNG middleware validates the JWT signature, extracts the user's identity, and stores the session in Redis with a 3600-second TTL.
- All subsequent database queries are scoped to the user's
customer_id.
Tip: Access tokens expire after 1 hour. Use the Supabase client's built-in token refresh to keep sessions alive without prompting the user to sign in again.
Per-User API Keys
Per-user API keys are the recommended way to authenticate programmatic access. They are scoped to your user account and workspace, support fine-grained permission scopes, and are stored as SHA-256 hashes. Generate keys from Settings > Developer or via the API Keys API.
Key Format
lvng_sk_live_7e8949d627f560d298f310ceeadb492c
│ │ └── 32 random hex characters
│ └── Environment (live / test)
└── Prefix (per-user key identifier)Sending the Key
The API accepts your key via three methods. All are equivalent.
Accepted Methods
AuthorizationheaderPass the key as a Bearer token: "Bearer lvng_sk_live_...". Recommended for all API calls.
x-api-keyheaderPass the full API key as the header value. Supported as an alternative to the Authorization header.
api_keyquery paramPass the key as a query parameter: ?api_key=lvng_sk_live_.... Use only when headers are not available.
curl Example
curl https://api.lvng.ai/api/v2/workflows \
-H "Authorization: Bearer lvng_sk_live_7e8949d627f560d298f310ceeadb492c"Claude Code Setup
Connect Claude Code to your workspace by adding the LVNG MCP server to your Claude settings:
// ~/.claude/settings.json
{
"mcpServers": {
"lvng": {
"command": "npx",
"args": ["@lvng/mcp-server"],
"env": {
"LVNG_API_KEY": "lvng_sk_live_..."
}
}
}
}Plan-Based Rate Limits
Request Context
After successful authentication, the middleware populates req.user with the following fields. All downstream handlers use this context for tenant-scoped operations.
{
"id": "user-uuid",
"customer_id": "customer-uuid",
"email": "user@example.com",
"role": "admin",
"auth_method": "jwt", // "jwt" or "per_user_api_key"
"scopes": ["read", "write"], // present for API key auth
"workspace_id": "ws-uuid", // present for API key auth
"organization_id": "org-uuid", // present if user belongs to an org
"org_role": "owner" // present if user belongs to an org
}Public Endpoints
The following endpoints do not require authentication. They are rate-limited by IP address (60 req/min).
/healthServer health check/capabilitiesPlatform capability discovery/v2/discoverAPI discovery endpoint/v2/ingestData ingestion webhook/v2/artifacts/metaArtifact metadata (public)/analytics/eventsAnalytics event ingestionTenant Isolation
LVNG is a multi-tenant platform. Every authentication method resolves to a customer_id. All database queries, agent executions, and workflow runs are automatically scoped to that tenant.
- •A JWT encodes the
customer_idin its claims. The middleware extracts it on every request. - •A per-user API key (
lvng_sk_*) is validated against a SHA-256 hash in the database, which returns the associateduser_idandcustomer_id. - •There is no way to query data belonging to another tenant, even with a valid token.
Security Notes
- 1.Never expose API keys in client-side code. API keys are for server environments only. Use JWT tokens for browser-based applications.
- 2.service_role keys are blocked on public endpoints. The middleware rejects Supabase service_role keys on user-facing routes to prevent privilege escalation.
- 3.API key versioning. The server tracks key versions via the
X-API-Key-Versionresponse header. Use this to verify your key is current after rotation. - 4.Rotate keys periodically. Generate new keys and revoke old ones from Settings > Developer or via the API Keys API.
- 5.Use environment variables. Never hard-code keys in source files. Add
.envto your.gitignore.
Environment Variables
Store your credentials in environment variables.
# .env -- add this file to .gitignore
LVNG_API_KEY=lvng_sk_live_7e8949d627f560d298f310ceeadb492c
# Optional: override the base URL for self-hosted deployments
LVNG_API_URL=https://api.lvng.ai