578 lines
16 KiB
Markdown
578 lines
16 KiB
Markdown
# 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. |