Overview
| Method | Use Case | Token Lifetime |
|---|---|---|
| API Key | Server-to-server, CI/CD, automation | Long-lived (until revoked) |
| JWT (Auth0) | Interactive clients, MCP servers | Short-lived (configurable) |
Both methods use the Authorization: Bearer <token> header. The API determines the token type automatically.
API Key Authentication
API keys are the simplest way to authenticate. Create a key via the API or the Lev platform, then include it in every request:
curl -X GET "https://api.levcapital.com/api/external/v2/build/deals" \
-H "Authorization: Bearer lev_sk_abc123def456..." \
-H "X-Origin-App: my-integration"API keys are scoped to a specific user and account. The key inherits the user's permissions — a key cannot access resources the user doesn't have access to.
Key validation
You can validate a key programmatically to check its scopes and associated account:
/api/external/v2/auth/validate-api-keyValidate an API key (unauthenticated endpoint)
{
"api_key": "lev_sk_abc123def456..."
}Returns { "valid": true, "user_id": ..., "account_id": ..., "scopes": [...], "tier": "..." } if valid, or { "valid": false } if invalid.
JWT Authentication
For interactive applications (like MCP servers connecting via OAuth), the API accepts Auth0-issued JWT tokens:
curl -X GET "https://api.levcapital.com/api/external/v2/build/deals" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "X-Origin-App: claude-desktop"JWT tokens are obtained through the OAuth 2.1 + PKCE flow. The MCP server handles this automatically for MCP clients like Claude Desktop and Cursor.
Required Headers
Every request must include:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <api_key_or_jwt> |
X-Origin-App | Yes | Identifies the calling application (e.g., my-integration, claude-desktop) |
X-Active-Account | For multi-account users | Account slug to scope the request to. Required on v2 requests when the authenticated user belongs to more than one account. Optional for single-account users. Not read for API-key auth — API keys are bound to a specific account at issuance, so the account is already implied. See Multi-Account Access. |
Content-Type | For POST/PATCH | application/json |
Idempotency-Key | Recommended for writes | UUID to prevent duplicate operations (24-hour expiry) |
Authentication Errors
| Status | Meaning |
|---|---|
401 Unauthorized | Missing, invalid, or expired token |
403 Forbidden | Valid token but insufficient permissions for this resource |
{
"request_id": "...",
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired authentication token"
}
}