Authentication
Bulutistan LLMaaS supports two authentication methods: API Keys and JWT Tokens.
API Keys
API keys are the recommended method for programmatic access.
Format
sk-proj-{random_string}
Usage
Include your API key in the Authorization header:
Authorization: Bearer sk-proj-your-api-key
Creating API Keys
- Log in to the Portal
- Navigate to API Keys
- Click Create Key
- Choose a key type:
- Inference for OpenAI-compatible model calls
- Management for public portal automation such as usage, billing, and limits
- Select the API scopes the key should have
- Copy the key immediately - it won't be shown again
Key Management
- Multiple Keys: Create separate keys for different applications
- Key Names: Use descriptive names for easy identification
- Rotation: Regularly rotate keys for security
- Revocation: Delete compromised keys immediately
JWT Tokens
JWT tokens are used for user session authentication (Portal access).
Self-service registration is currently unavailable and returns a 503 Service Unavailable response. New users are onboarded via invitation links sent by organization admins or platform administrators.
Obtaining Tokens
curl -X POST https://api.bulutistan.ai/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your-password"
}'
Response
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer",
"expires_in": 1800,
"user": {
"id": "uuid",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"tenant_id": "uuid",
"is_active": true,
"created_at": "2024-01-01T00:00:00Z",
"email_verified": true,
"onboarding_completed": true
}
}
Token Lifetimes
| Token | Lifetime |
|---|---|
| Access token | 30 minutes |
| Refresh token | 7 days |
The access token expires after 30 minutes. Use the refresh token to obtain a new access token without requiring the user to log in again.
Usage
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Endpoint Path Prefixes
The platform exposes endpoints under two prefixes. Both route to the same handlers for inference; management endpoints are only under /api/v1/*.
/v1/*— use this when configuring the OpenAI SDKbase_url. Example:OpenAI(base_url="https://api.example.com/v1")— the SDK appends paths like/chat/completionsitself, so the final URL becomeshttps://api.example.com/v1/chat/completions./api/v1/*— use this for direct HTTP requests (curl, raw fetch) and for all platform management endpoints (profile, api-keys, billing, usage, jobs).
API Key Types and Scopes
Bulutistan LLMaaS separates API keys by purpose.
Inference Keys
Use an Inference key with OpenAI-compatible SDKs and direct inference HTTP calls. Inference endpoints are available under both /v1/* and /api/v1/*.
| API Scope | Endpoints |
|---|---|
inference:chat | POST /v1/chat/completions, POST /api/v1/chat/completions |
inference:completions | POST /v1/completions, POST /api/v1/completions |
inference:embeddings | POST /v1/embeddings, POST /api/v1/embeddings |
inference:images | POST /v1/images/generations, POST /api/v1/images/generations |
models:list | GET /v1/models, GET /api/v1/models |
models:retrieve | GET /v1/models/{model_id}, GET /api/v1/models/{model_id} |
jobs:stats_own | GET /api/v1/jobs/stats |
jobs:read_own | GET /api/v1/jobs, GET /api/v1/jobs/{job_id} |
jobs:cancel_own | POST /api/v1/jobs/{job_id}/cancel |
Submit async jobs through the inference endpoints with the background/async request option; POST /api/v1/jobs and DELETE /api/v1/jobs/{job_id} are not public API-key operations.
Management Keys
Use a Management key for public portal automation. Management keys cannot call inference endpoints.
| API Scope | Endpoints |
|---|---|
usage:read_current | GET /api/v1/usage/current |
usage:read_history | GET /api/v1/usage/history |
usage:read_summary | GET /api/v1/usage/summary |
usage:read_report | GET /api/v1/usage/report |
usage:read_breakdown | GET /api/v1/usage/tenant-breakdown (tenant admin/owner only) |
billing:read_current | GET /api/v1/billing/current (tenant admin/owner only) |
billing:read_cycles | GET /api/v1/billing/cycles, GET /api/v1/billing/cycle/{cycle_id} (tenant admin/owner only) |
billing:read_invoices | GET /api/v1/billing/invoices, GET /api/v1/billing/invoice/{cycle_id} (tenant admin/owner only) |
billing:read_summary | GET /api/v1/billing/summary (tenant admin/owner only) |
profile:read | GET /api/v1/profile, GET /api/v1/auth/profile |
rate_limits:read | GET /api/v1/rate-limits, GET /api/v1/profile/rate-limits |
budgets:read_own | GET /api/v1/profile/cost-limit |
budgets:update_own | PUT /api/v1/profile/cost-limit, DELETE /api/v1/profile/cost-limit |
usage:read_current, usage:read_history, usage:read_summary, and usage:read_report return the key owner's personal usage by default. Admin and owner users can request tenant-level usage where the endpoint supports a scope=tenant query parameter. usage:read_breakdown and billing scopes are only useful for tenant admin/owner users; usage:read_breakdown is hidden from other users in the portal.
Public API keys do not manage organizations, members, API key creation, or admin portal resources. Use a browser/JWT session for those workflows.
If a key calls an endpoint outside the public API-key surface, you will receive a 403 Forbidden error:
{
"error": {
"message": "API keys cannot access this endpoint.",
"type": "authentication_error"
}
}
If the endpoint is available to API keys but the key is missing the required capability, the error message names the missing scope.
Security Best Practices
- Never share API keys in public repositories
- Use environment variables for key storage
- Rotate keys periodically
- Use separate keys for development and production
- Monitor usage for unexpected activity
Rate Limits
Authentication affects rate limits:
| Auth Type | Rate Limit |
|---|---|
| API Key | Per-key limits |
| JWT Token | Per-user limits |
See Rate Limiting for details.