# Banatie API - Administration & Authentication ## Authentication Overview All API endpoints (except public endpoints and bootstrap) require authentication via API key in the `X-API-Key` header. ### API Key Types **Master Keys** - Full administrative access - Never expire - Can create and revoke other API keys - Access to all admin endpoints **Project Keys** - Standard access for image generation - Expire in 90 days by default - Scoped to specific organization and project - Rate limited (100 requests/hour) ### Header Format ``` X-API-Key: bnt_your_key_here ``` --- ## Public Endpoints ### GET /health Health check with server status. **Authentication:** None **Purpose:** Monitor API availability and uptime **Returns:** Status, timestamp, uptime, environment, version --- ### GET /api/info API information and configuration limits. **Authentication:** Optional (returns key info if authenticated) **Purpose:** Discover API capabilities and limits **Returns:** API name, version, endpoints list, file size/format limits --- ## Bootstrap Endpoint ### POST /api/bootstrap/initial-key Create the first master API key (one-time only). **Authentication:** None (public, works only when database is empty) **Purpose:** Initialize the API with first master key **Notes:** - Only works when no API keys exist in database - Returns master key value (save securely, shown only once) - Subsequent calls return 403 Forbidden --- ## API Key Management All endpoints require Master Key authentication. ### POST /api/admin/keys Create new API key (master or project). **Authentication:** Master Key required **Parameters:** - `type` - "master" or "project" (required) - `projectId` - Project identifier (required for project keys) - `organizationId` - Organization UUID (optional, auto-created) - `organizationSlug` - Organization slug (optional, auto-created) - `projectSlug` - Project slug (optional, auto-created) - `name` - Friendly name for the key (optional) - `expiresInDays` - Expiration days (optional, default: 90 for project keys) **Purpose:** Generate new API keys for projects or admin users **Notes:** - Automatically creates organization and project if they don't exist - Returns API key value (save securely, shown only once) - Master keys never expire, project keys expire in 90 days by default --- ### GET /api/admin/keys List all API keys. **Authentication:** Master Key required **Purpose:** View all active and inactive API keys **Returns:** Array of all keys with metadata (no sensitive key values), includes organization and project details **Notes:** - Shows all keys regardless of active status - Includes last used timestamp - Does not return actual API key values (hashed in database) --- ### DELETE /api/admin/keys/:keyId Revoke an API key. **Authentication:** Master Key required **Parameters:** - `keyId` - UUID of the key to revoke (path parameter) **Purpose:** Deactivate an API key (soft delete) **Notes:** - Soft delete via `is_active` flag - Revoked keys cannot be reactivated - Key remains in database for audit trail --- ## Rate Limiting ### API Key Rate Limiting Rate limits apply per API key to protected endpoints. **Limits:** - **Project Keys:** 100 requests per hour - **Master Keys:** No rate limit on admin endpoints **Affected Endpoints:** - All `/api/v1/generations` endpoints (POST, PUT, regenerate) - All `/api/v1/images` endpoints (POST upload, PUT) - All `/api/v1/flows` endpoints (PUT, regenerate) - All `/api/v1/live/scopes` endpoints (POST, PUT, regenerate, DELETE) **Response Headers:** - `X-RateLimit-Limit` - Maximum requests per window - `X-RateLimit-Remaining` - Requests remaining - `X-RateLimit-Reset` - Reset timestamp (ISO 8601) **429 Too Many Requests:** - Returned when limit exceeded - Includes `Retry-After` header (seconds until reset) --- ### IP-Based Rate Limiting (Live URLs) Separate rate limiting for public live URL generation endpoints. **Limits:** - **10 new generations per hour per IP address** - Only cache MISS (new generations) count toward limit - Cache HIT (cached images) do NOT count toward limit **Affected Endpoints:** - `GET /:orgSlug/:projectSlug/live/:scope` - Public live URL generation **Purpose:** - Prevent abuse of public live URL endpoints - Separate from API key limits (for authenticated endpoints) - Does not affect API key-authenticated endpoints **Response Headers:** - `X-RateLimit-Limit` - Maximum requests per window (10) - `X-RateLimit-Remaining` - Requests remaining - `X-RateLimit-Reset` - Seconds until reset **429 Too Many Requests:** - Returned when IP limit exceeded - Includes `Retry-After` header (seconds until reset) - Error code: `IP_RATE_LIMIT_EXCEEDED` **Notes:** - Uses in-memory store with automatic cleanup - Supports X-Forwarded-For header for proxy/load balancer setups - IP limit resets every hour per IP address --- ## Error Codes ### HTTP Status Codes | Code | Description | |------|-------------| | 401 | Unauthorized - Missing, invalid, expired, or revoked API key | | 403 | Forbidden - Insufficient permissions (master key required) | | 409 | Conflict - Resource already exists (e.g., duplicate scope slug) | | 429 | Too Many Requests - Rate limit exceeded (API key or IP) | ### Authentication Error Codes | Error Code | HTTP Status | Description | |------------|-------------|-------------| | `MISSING_API_KEY` | 401 | No X-API-Key header provided | | `INVALID_API_KEY` | 401 | Key is invalid, expired, or revoked | | `MASTER_KEY_REQUIRED` | 403 | Endpoint requires master key, project key insufficient | | `BOOTSTRAP_NOT_ALLOWED` | 403 | Keys already exist, cannot bootstrap again | ### Rate Limiting Error Codes | Error Code | HTTP Status | Description | |------------|-------------|-------------| | `RATE_LIMIT_EXCEEDED` | 429 | API key rate limit exceeded (100/hour) | | `IP_RATE_LIMIT_EXCEEDED` | 429 | IP rate limit exceeded for live URLs (10/hour) | ### Live Scope Error Codes | Error Code | HTTP Status | Description | |------------|-------------|-------------| | `SCOPE_INVALID_FORMAT` | 400 | Scope slug format invalid (must be alphanumeric + hyphens + underscores) | | `SCOPE_ALREADY_EXISTS` | 409 | Scope with this slug already exists in project | | `SCOPE_NOT_FOUND` | 404 | Scope does not exist or access denied | | `IMAGE_NOT_IN_SCOPE` | 400 | Image does not belong to specified scope | **Notes:** - All error responses follow the format: `{ "success": false, "error": { "message": "...", "code": "..." } }` - Rate limit errors include `Retry-After` header with seconds until reset - Scope management endpoints require project key authentication