# Banatie API Reference Banatie is a REST API service for AI-powered image generation using the Gemini Flash Image model. ## Base URL ``` http://localhost:3000 ``` ## Authentication All API endpoints (except `/health`, `/api/info`, and `/api/bootstrap/*`) require authentication via API key. ### API Key Types 1. **Master Keys** - Full admin access, never expire, can create/revoke other keys 2. **Project Keys** - Standard access for image generation, expire in 90 days ### Using API Keys Include your API key in the `X-API-Key` header: ```bash curl -X POST http://localhost:3000/api/generate \ -H "X-API-Key: bnt_your_key_here" \ -F "prompt=..." \ -F "filename=..." ``` ### Getting Your First API Key 1. **Bootstrap** - Create initial master key (one-time only): ```bash curl -X POST http://localhost:3000/api/bootstrap/initial-key ``` 2. **Create Project Key** - Use master key to create project keys: ```bash curl -X POST http://localhost:3000/api/admin/keys \ -H "X-API-Key: YOUR_MASTER_KEY" \ -H "Content-Type: application/json" \ -d '{"type": "project", "projectId": "my-project", "name": "My Project Key"}' ``` **Important:** Save keys securely when created - they cannot be retrieved later! ## Content Types - **Request**: `multipart/form-data` for file uploads, `application/json` for JSON endpoints - **Response**: `application/json` ## Rate Limits All authenticated endpoints (those requiring API keys) are rate limited: - **Per API Key:** 100 requests per hour - **Applies to:** - `POST /api/generate` - `POST /api/text-to-image` - `POST /api/enhance` - **Not rate limited:** - Public endpoints (`GET /health`, `GET /api/info`) - Bootstrap endpoint (`POST /api/bootstrap/initial-key`) - Admin endpoints (require master key, but no rate limit) - Image serving endpoints (`GET /api/images/*`) Rate limit information included in response headers: - `X-RateLimit-Limit`: Maximum requests per window - `X-RateLimit-Remaining`: Requests remaining - `X-RateLimit-Reset`: When the limit resets (ISO 8601) **429 Too Many Requests:** Returned when limit exceeded with `Retry-After` header --- ## Endpoints ### Overview | Endpoint | Method | Authentication | Rate Limit | Description | |----------|--------|----------------|------------|-------------| | `/health` | GET | None | No | Health check | | `/api/info` | GET | None | No | API information | | `/api/bootstrap/initial-key` | POST | None (one-time) | No | Create first master key | | `/api/admin/keys` | POST | Master Key | No | Create new API keys | | `/api/admin/keys` | GET | Master Key | No | List all API keys | | `/api/admin/keys/:keyId` | DELETE | Master Key | No | Revoke API key | | `/api/generate` | POST | API Key | 100/hour | Generate images with files | | `/api/text-to-image` | POST | API Key | 100/hour | Generate images (JSON only) | | `/api/enhance` | POST | API Key | 100/hour | Enhance text prompts | | `/api/images/*` | GET | None | No | Serve generated images | --- ### Authentication & Admin #### `POST /api/bootstrap/initial-key` Create the first master API key. This endpoint works only once when no keys exist. **Authentication:** None required (public endpoint, one-time use) **Response (201):** ```json { "apiKey": "bnt_...", "type": "master", "name": "Initial Master Key", "expiresAt": null, "message": "IMPORTANT: Save this key securely. You will not see it again!" } ``` **Error (403):** ```json { "error": "Bootstrap not allowed", "message": "API keys already exist. Use /api/admin/keys to create new keys." } ``` --- #### `POST /api/admin/keys` Create a new API key (master or project). **Authentication:** Master key required via `X-API-Key` header **Request Body:** ```json { "type": "master | project", "projectId": "required-for-project-keys", "name": "optional-friendly-name", "expiresInDays": 90 } ``` **Response (201):** ```json { "apiKey": "bnt_...", "metadata": { "id": "uuid", "type": "project", "projectId": "my-project", "name": "My Project Key", "expiresAt": "2025-12-29T17:08:02.536Z", "scopes": ["generate", "read"], "createdAt": "2025-09-30T17:08:02.553Z" }, "message": "IMPORTANT: Save this key securely. You will not see it again!" } ``` --- #### `GET /api/admin/keys` List all API keys. **Authentication:** Master key required **Response (200):** ```json { "keys": [ { "id": "uuid", "type": "master", "projectId": null, "name": "Initial Master Key", "scopes": ["*"], "isActive": true, "createdAt": "2025-09-30T17:01:23.456Z", "expiresAt": null, "lastUsedAt": "2025-09-30T17:08:45.123Z", "createdBy": null } ], "total": 1 } ``` --- #### `DELETE /api/admin/keys/:keyId` Revoke an API key (soft delete). **Authentication:** Master key required **Response (200):** ```json { "message": "API key revoked successfully", "keyId": "uuid" } ``` --- ### Health Check #### `GET /health` Health check endpoint with server status. **Response:** ```json { "status": "healthy", "timestamp": "2023-11-20T10:00:00.000Z", "uptime": 12345.67, "environment": "development", "version": "1.0.0" } ``` --- ### API Information #### `GET /api/info` Returns API metadata and configuration limits. **Response:** ```json { "name": "Banatie - Nano Banana Image Generation API", "version": "1.0.0", "description": "REST API service for AI-powered image generation using Gemini Flash Image model", "endpoints": { "GET /health": "Health check", "GET /api/info": "API information", "POST /api/generate": "Generate images from text prompt with optional reference images", "POST /api/text-to-image": "Generate images from text prompt only (JSON)", "POST /api/enhance": "Enhance and optimize prompts for better image generation" }, "limits": { "maxFileSize": "5MB", "maxFiles": 3, "supportedFormats": ["PNG", "JPEG", "JPG", "WebP"] } } ``` --- ### Generate Image #### `POST /api/generate` Generate images from text prompts with optional reference images. **Authentication:** API key required (master or project) **Rate Limit:** 100 requests per hour per API key **Content-Type:** `multipart/form-data` **Parameters:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `prompt` | string | Yes | Text description of the image to generate (1-5000 chars) | | `filename` | string | Yes | Desired filename for the generated image | | `files` | file[] | No | Reference images (max 3 files, 5MB each) | | `autoEnhance` | boolean | No | Enable automatic prompt enhancement | | `enhancementOptions` | object | No | Enhancement configuration options | **Enhancement Options:** | Field | Type | Options | Default | Description | |-------|------|---------|---------|-------------| | `template` | string | `photorealistic`, `illustration`, `minimalist`, `sticker`, `product`, `comic`, `general` | `photorealistic` | Prompt engineering template to apply | **Example Request:** ```bash curl -X POST http://localhost:3000/api/generate \ -H "X-API-Key: bnt_your_api_key_here" \ -F "prompt=A majestic mountain landscape at sunset" \ -F "filename=mountain-sunset" \ -F "autoEnhance=true" \ -F "files=@reference1.jpg" \ -F "files=@reference2.png" ``` **Success Response (200):** ```json { "success": true, "message": "Image generated successfully", "data": { "filename": "mountain-sunset-20231120-100000.png", "filepath": "./results/mountain-sunset-20231120-100000.png", "description": "Generated image description", "model": "gemini-1.5-flash", "generatedAt": "2023-11-20T10:00:00.000Z", "promptEnhancement": { "originalPrompt": "A mountain landscape", "enhancedPrompt": "A majestic mountain landscape at golden hour with dramatic lighting", "detectedLanguage": "en", "appliedTemplate": "scenic_landscape", "enhancements": ["lighting_enhancement", "composition_improvement"] } } } ``` **Error Response (400/500):** ```json { "success": false, "message": "Image generation failed", "error": "Validation failed: Prompt is required" } ``` --- ### Text-to-Image (JSON) #### `POST /api/text-to-image` Generate images from text prompts only using JSON payload. Simplified endpoint for text-only requests without file uploads. **Authentication:** API key required (master or project) **Rate Limit:** 100 requests per hour per API key **Content-Type:** `application/json` **Request Body:** ```json { "prompt": "A beautiful sunset over mountains", "filename": "sunset_image", "aspectRatio": "16:9", "autoEnhance": true, "enhancementOptions": { "template": "photorealistic", "mood": "peaceful", "lighting": "golden hour" } } ``` **Parameters:** | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `prompt` | string | Yes | - | Text description of the image to generate (3-2000 chars) | | `filename` | string | Yes | - | Desired filename for the generated image (alphanumeric, underscore, hyphen only) | | `aspectRatio` | string | No | `"1:1"` | Image aspect ratio (`"1:1"`, `"2:3"`, `"3:2"`, `"3:4"`, `"4:3"`, `"4:5"`, `"5:4"`, `"9:16"`, `"16:9"`, `"21:9"`) | | `autoEnhance` | boolean | No | `true` | Enable automatic prompt enhancement (set to `false` to use prompt as-is) | | `enhancementOptions` | object | No | - | Enhancement configuration options | | `meta` | object | No | - | Metadata for request tracking | **Enhancement Options:** | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `template` | string | No | `"photorealistic"` | Prompt engineering template: `"photorealistic"`, `"illustration"`, `"minimalist"`, `"sticker"`, `"product"`, `"comic"`, `"general"` | **Meta Object:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `tags` | string[] | No | Array of string tags for tracking/grouping requests (not stored, only logged) | **Example Request:** ```bash curl -X POST http://localhost:3000/api/text-to-image \ -H "X-API-Key: bnt_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A beautiful sunset over mountains with golden clouds", "filename": "test_sunset", "aspectRatio": "16:9", "autoEnhance": true, "enhancementOptions": { "template": "photorealistic" }, "meta": { "tags": ["demo", "sunset"] } }' ``` **Success Response (200):** ```json { "success": true, "message": "Image generated successfully", "data": { "filename": "test_sunset.png", "filepath": "results/test_sunset.png", "description": "Here's a beautiful sunset over mountains with golden clouds for you!", "model": "Nano Banana", "generatedAt": "2025-09-26T15:04:27.705Z", "promptEnhancement": { "originalPrompt": "A beautiful sunset over mountains", "enhancedPrompt": "A breathtaking photorealistic sunset over majestic mountains...", "detectedLanguage": "English", "appliedTemplate": "landscape", "enhancements": ["lighting_enhancement", "composition_improvement"] } } } ``` **Error Response (400/500):** ```json { "success": false, "message": "Validation failed", "error": "Prompt is required" } ``` **Key Differences from /api/generate:** - **JSON only**: No file upload support - **Faster**: No multipart parsing overhead - **Simpler testing**: Easy to use with curl or API clients - **Same features**: Supports all enhancement options - **Auto-enhance by default**: `autoEnhance` defaults to `true`, set explicitly to `false` to use prompt as-is **Template Descriptions:** - `photorealistic`: Photography-focused with camera angles, lens types, lighting, and fine details - `illustration`: Art style specifications with line work, color palette, and shading techniques - `minimalist`: Emphasis on negative space, simple composition, and subtle elements - `sticker`: Bold outlines, kawaii style, clean design, transparent background style - `product`: Studio lighting setups, commercial photography terms, surfaces, and angles - `comic`: Panel style, art technique, mood, and dialogue/caption integration - `general`: Balanced approach with clear descriptions and artistic detail --- ### Enhance Prompt #### `POST /api/enhance` Enhance and optimize text prompts for better image generation results. **Authentication:** API key required (master or project) **Rate Limit:** 100 requests per hour per API key **Content-Type:** `application/json` **Request Body:** ```json { "prompt": "A mountain landscape", "options": { "imageStyle": "photorealistic", "aspectRatio": "landscape", "mood": "serene and peaceful", "lighting": "golden hour", "cameraAngle": "wide shot", "outputFormat": "detailed", "negativePrompts": ["blurry", "low quality"] } } ``` **Parameters:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `prompt` | string | Yes | Original text prompt (1-5000 chars) | | `options` | object | No | Enhancement configuration | **Success Response (200):** ```json { "success": true, "originalPrompt": "A mountain landscape", "enhancedPrompt": "A breathtaking photorealistic mountain landscape during golden hour, featuring dramatic peaks and valleys with warm, soft lighting creating a serene and peaceful atmosphere, captured in a wide shot composition with rich detail and depth", "detectedLanguage": "en", "appliedTemplate": "scenic_landscape", "metadata": { "style": "photorealistic", "aspectRatio": "landscape", "enhancements": [ "lighting_enhancement", "composition_improvement", "atmosphere_addition", "detail_specification" ] } } ``` **Error Response (400/500):** ```json { "success": false, "originalPrompt": "A mountain landscape", "error": "Validation failed: Prompt is required" } ``` --- ## Error Codes | Code | Description | |------|-------------| | 400 | Bad Request - Invalid parameters or validation failure | | 401 | Unauthorized - Missing, invalid, expired, or revoked API key | | 403 | Forbidden - Insufficient permissions (e.g., master key required) | | 404 | Not Found - Endpoint or resource does not exist | | 429 | Too Many Requests - Rate limit exceeded | | 500 | Internal Server Error - Server configuration or processing error | ## Common Error Messages ### Authentication Errors (401) - `"Missing API key"` - No X-API-Key header provided - `"Invalid API key"` - The provided API key is invalid, expired, or revoked - **Affected endpoints:** `/api/generate`, `/api/text-to-image`, `/api/enhance`, `/api/admin/*` ### Authorization Errors (403) - `"Master key required"` - This endpoint requires a master API key (not project key) - `"Bootstrap not allowed"` - API keys already exist, cannot bootstrap again - **Affected endpoints:** `/api/admin/*`, `/api/bootstrap/initial-key` ### Validation Errors (400) - `"Prompt is required"` - Missing or empty prompt parameter - `"Reference image validation failed"` - Invalid file format or size - `"Validation failed"` - Parameter validation error ### Rate Limiting Errors (429) - `"Rate limit exceeded"` - Too many requests, retry after specified time - **Applies to:** `/api/generate`, `/api/text-to-image`, `/api/enhance` - **Rate limit:** 100 requests per hour per API key - **Response includes:** `Retry-After` header with seconds until reset ### Server Errors - `"Server configuration error"` - Missing GEMINI_API_KEY or database connection - `"Image generation failed"` - AI service error - `"Authentication failed"` - Error during authentication process --- ## File Upload Specifications **Supported Formats:** PNG, JPEG, JPG, WebP **Maximum File Size:** 5MB per file **Maximum Files:** 3 files per request **Storage:** Temporary files in `./uploads/temp`, results in `./results` ## Request Headers | Header | Value | Description | |--------|-------|-------------| | `X-API-Key` | string | API key for authentication (required for most endpoints) | | `X-Request-ID` | string | Unique request identifier (auto-generated by server) | ## Response Headers | Header | Description | |--------|-------------| | `X-Request-ID` | Request identifier for tracking | | `X-RateLimit-Limit` | Maximum requests allowed per window | | `X-RateLimit-Remaining` | Requests remaining in current window | | `X-RateLimit-Reset` | When the rate limit resets (ISO 8601) | ## CORS Cross-origin requests supported from: - `http://localhost:3001` (Landing Page) - `http://localhost:3002` (Studio Platform) - `http://localhost:3003` (Admin Dashboard) Configure additional origins via `CORS_ORIGIN` environment variable.