Authentication
JWT tokens and API keys for accessing the dbtrail API
Most API endpoints are prefixed with https://api.dbtrail.com/api/v1/. The Claude integration endpoint is at /mcp (no version prefix). Authentication is required for all endpoints.
dbtrail supports two authentication methods: JWT tokens for browser sessions and API keys for programmatic access.
JWT authentication
JWTs are short-lived tokens issued by Supabase GoTrue after an OAuth or email/password login. They are used by the dashboard (React frontend) and are not typically used directly by API consumers.
| Property | Value |
|---|---|
| Issuer | Supabase GoTrue |
| Lifetime | 1 hour (auto-refreshed) |
| Tenant resolution | Via X-Tenant-ID header |
| Use case | Browser sessions |
Headers required
Authorization: Bearer <jwt_token>
X-Tenant-ID: <tenant_uuid>The X-Tenant-ID header is required because a user can belong to multiple tenants. If the user belongs to only one tenant, the header can be omitted and the tenant is resolved automatically.
API key authentication
API keys are long-lived, static tokens for machine-to-machine scenarios: AI assistants (Claude, Cursor), scripts, CI/CD pipelines, and the dbtrail agent.
| Property | Value |
|---|---|
| Issuer | dbtrail dashboard |
| Lifetime | Until revoked or expired |
| Tenant resolution | Automatic (embedded in key lookup) |
| Use case | Claude, scripts, agents |
Headers required
Authorization: Bearer bt_live_<32_hex_chars>No tenant header needed
API keys embed the tenant via a lookup table, so the X-Tenant-ID header is not needed for API key authentication. The tenant is resolved automatically during key validation.
Key format
bt_live_<32 random hex characters>
Example: bt_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6| Segment | Purpose |
|---|---|
bt_ | Identifies this as a dbtrail key (greppable in logs) |
live_ | Environment indicator (test_ reserved for future sandbox keys) |
| 32 hex chars | 128 bits of entropy (16 random bytes) |
Validation flow
For API keys, the validation process is:
- Format check — reject if key doesn't match
bt_(live|test)_[0-9a-f]{32} - Hash and lookup — SHA-256 hash the key, query the
api_key_lookuptable - Revocation check — verify the key hasn't been revoked
- Expiry check — check
expires_atagainst current UTC time - Return context — user ID, tenant ID, tenant slug, role, and plan
Comparison
| Aspect | JWT | API Key |
|---|---|---|
| Issued by | Supabase GoTrue | dbtrail dashboard |
| Lifetime | Short (1 hour) | Long-lived (until revoked/expired) |
| Contains tenant? | No (via header) | Yes (embedded via lookup) |
X-Tenant-ID header | Required | Not needed |
| Use case | Browser sessions | Claude, scripts, agents |
Rate limiting
Both authentication methods are subject to rate limiting based on the tenant's plan. Limits are enforced per-user and per-tenant independently:
| Plan | Per-user (rpm) | Per-tenant (rpm) |
|---|---|---|
| Free | 60 | 120 |
| Pro | 200 | 600 |
| Premium | 600 | 2,000 |
| Enterprise | 2,000 | 10,000 |