Authentication

The LVNG API supports two authentication methods: JWT tokens (via Supabase) for user sessions, and API keys for programmatic access. Both methods resolve to a tenant-scoped request context that isolates all data operations.

Overview

MethodHeaderBest For
JWT TokenAuthorization: Bearer <jwt>Browser apps, user sessions
API Keyx-api-key: <key>Backend services, scripts, CI/CD

JWT 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:

JWT Payload
{
  400">class="text-emerald-400">"userId": 400">class="text-emerald-400">"uuid-of-the-user",
  400">class="text-emerald-400">"email": 400">class="text-emerald-400">"user@example.com",
  400">class="text-emerald-400">"role": 400">class="text-emerald-400">"admin",
  400">class="text-emerald-400">"organizationId": 400">class="text-emerald-400">"org-uuid",
  400">class="text-emerald-400">"iat": 1710864000,
  400">class="text-emerald-400">"exp": 1710867600
}

Token Lifetime

Token TypeTTL
Access token1 hour
Refresh token7 days
Redis session cache3600 seconds

Request Example

Terminal -- JWT Auth
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/channels \
  -H 400">class="text-emerald-400">"Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H 400">class="text-emerald-400">"Content-Type: application/json"

How It Works

  1. The user signs in via Supabase Auth (email/password, OAuth, or magic link).
  2. Supabase returns an access token (JWT) and a refresh token.
  3. Your frontend sends the access token in the Authorization header with every request.
  4. The LVNG middleware validates the JWT signature, extracts the user's identity, and stores the session in Redis with a 3600-second TTL.
  5. 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.

API Keys

API keys are designed for server-to-server communication where there is no browser session. They are long-lived credentials tied to a specific customer account and stored as bcrypt hashes in the api_keys database table with a 30-second in-memory cache for performance.

Key Format

LVNG API keys follow a fixed format that encodes the customer scope. The token portion is 32-64 random characters.

Key Format
vtron_cust_{customerId}_{token}

# Example:
vtron_cust_abc123_sk_live_9f8e7d6c5b4a3210fedcba98

Sending the Key

The API accepts your key via three methods. All are equivalent.

Accepted Methods

x-api-keyheader

Pass the full API key as the header value. Recommended for server-to-server calls.

Authorizationheader

Pass the key as a Bearer token: "Bearer vtron_cust_...". Works when your HTTP client already sets Authorization headers.

api_keyquery param

Pass the key as a query parameter: ?api_key=vtron_cust_.... Use only when headers are not available.

curl Example (x-api-key)

Terminal -- x-api-key
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v1/chat \
  -H 400">class="text-emerald-400">"x-api-key: vtron_cust_abc123_sk_live_9f8e7d6c5b4a3210fedcba98" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"message": 400">class="text-emerald-400">"Summarize yesterday'\''s standup notes.",
    400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"api"
  }'

Plan-Based Rate Limits

API keys are associated with a plan tier that determines rate limits.

PlanPer MinutePer HourPer Day
Free520100
Pro10050010,000
EnterpriseUnlimitedUnlimitedUnlimited

Request Context

After successful authentication, the middleware populates req.user with the following fields. All downstream handlers use this context for tenant-scoped operations.

req.user object
{
  400">class="text-emerald-400">"id": 400">class="text-emerald-400">"user-uuid",
  400">class="text-emerald-400">"customer_id": 400">class="text-emerald-400">"customer-uuid",
  400">class="text-emerald-400">"email": 400">class="text-emerald-400">"user@example.com",
  400">class="text-emerald-400">"role": 400">class="text-emerald-400">"admin",
  400">class="text-emerald-400">"auth_method": 400">class="text-emerald-400">"jwt",       400">class="text-zinc-500">// 400">class="text-emerald-400">"jwt" or 400">class="text-emerald-400">"api_key"
  400">class="text-emerald-400">"organization_id": 400">class="text-emerald-400">"org-uuid",  400">class="text-zinc-500">// present 400">if user belongs to an org
  400">class="text-emerald-400">"org_role": 400">class="text-emerald-400">"owner"             400">class="text-zinc-500">// present 400">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 ingestion

Tenant 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_id in its claims. The middleware extracts it on every request.
  • An API key embeds the customer_id directly in the key prefix (vtron_cust_{customerId}_...). The middleware parses it and enforces scope.
  • 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-Version response header. Use this to verify your key is current after rotation.
  • 4.Rotate keys periodically. Generate new keys and revoke old ones from Settings > API Keys in the dashboard.
  • 5.Use environment variables. Never hard-code keys in source files. Add .env to your .gitignore.

Environment Variables

Store your credentials in environment variables.

.env
# .env -- add this file to .gitignore
LVNG_API_KEY=vtron_cust_abc123_sk_live_9f8e7d6c5b4a3210fedcba98

# Optional: override the base URL for self-hosted deployments
LVNG_API_URL=https:400">class="text-zinc-500">//api.lvng.ai/api

Next Steps