# 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
