Skip to content

API Authentication

The Expose API uses JWT tokens for user authentication and API keys for programmatic access.

Authentication Methods

JWT Tokens

Used for user sessions (web dashboard, app login):

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

API Keys

Used for tunnels and programmatic access:

Authorization: Bearer exp_k1_7f8a9b...

Obtaining Credentials

Register a New User

POST /api/v1/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-secure-password"
}

Response:

{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"created_at": "2024-01-15T10:30:00Z"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}

Login

POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-secure-password"
}

Response:

{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"created_at": "2024-01-15T10:30:00Z"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}

Create API Key

POST /api/v1/api-keys
Authorization: Bearer <jwt_token>
Content-Type: application/json
{
"name": "MacBook Pro"
}

Response:

{
"api_key": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"name": "MacBook Pro",
"key_prefix": "exp_k1_7f8a9b",
"created_at": "2024-01-15T10:30:00Z",
"last_used_at": null
},
"key": "exp_k1_7f8a9b..."
}

Token Lifetime

Token TypeLifetime
JWT Token7 days
API KeyUntil revoked

Error Responses

401 Unauthorized

Missing or invalid token:

{
"error": "unauthorized",
"message": "Invalid or expired token"
}

403 Forbidden

Valid token but insufficient permissions:

{
"error": "forbidden",
"message": "You don't have permission to access this resource"
}

Best Practices

  1. Store tokens securely — Never in localStorage for web apps
  2. Use API keys for automation — Don’t use your JWT for scripts
  3. Rotate API keys — Create new keys periodically
  4. Revoke unused keys — Remove keys you no longer need
  5. Use HTTPS always — Tokens are sensitive data

Rate Limiting

API requests are rate limited:

EndpointLimit
Auth endpoints10/minute
General API100/minute
Tunnel dataUnlimited

When rate limited:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"error": "rate_limited",
"message": "Too many requests, please try again later"
}