Users & API Keys
Users
Get Current User
GET /api/v1/users/meAuthorization: Bearer <token>Response:
{ "id": "550e8400-e29b-41d4-a716-446655440000", "email": "user@example.com", "created_at": "2024-01-15T10:30:00Z"}Update Password
PUT /api/v1/users/me/passwordAuthorization: Bearer <token>Content-Type: application/json
{ "current_password": "old-password", "new_password": "new-secure-password"}Response:
{ "message": "Password updated successfully"}API Keys
List API Keys
GET /api/v1/api-keysAuthorization: Bearer <token>Response:
[ { "id": "660e8400-e29b-41d4-a716-446655440000", "name": "MacBook Pro", "key_prefix": "exp_k1_7f8a9b", "created_at": "2024-01-15T10:30:00Z", "last_used_at": "2024-01-20T14:00:00Z" }, { "id": "770e8400-e29b-41d4-a716-446655440000", "name": "CI Pipeline", "key_prefix": "exp_k1_3c4d5e", "created_at": "2024-01-10T08:00:00Z", "last_used_at": null }]Create API Key
POST /api/v1/api-keysAuthorization: Bearer <token>Content-Type: application/json
{ "name": "My New Key"}Response:
{ "api_key": { "id": "880e8400-e29b-41d4-a716-446655440000", "name": "My New Key", "key_prefix": "exp_k1_9a8b7c", "created_at": "2024-01-25T10:00:00Z", "last_used_at": null }, "key": "exp_k1_9a8b7c6d5e4f3a2b1c0d..."}Delete API Key
DELETE /api/v1/api-keys/{id}Authorization: Bearer <token>Response:
HTTP/1.1 204 No ContentAPI Key Format
API keys follow this format:
exp_k1_<random_bytes>exp— Expose prefixk1— Key version 1<random_bytes>— Cryptographically random identifier
Usage Tracking
The last_used_at field updates when an API key is used for:
- Tunnel authentication
- API requests
This helps identify unused keys for cleanup.
Error Responses
Key Not Found
HTTP/1.1 404 Not Found
{ "error": "not_found", "message": "API key not found"}Invalid Password
HTTP/1.1 400 Bad Request
{ "error": "invalid_password", "message": "Current password is incorrect"}Password Requirements
New passwords must:
- Be at least 8 characters
- Not match the current password
HTTP/1.1 400 Bad Request
{ "error": "validation_error", "message": "Password must be at least 8 characters"}