banatie-service/docs/api
Oleg Proskurin 237443194f feat: add file upload endpoint 2025-10-11 00:08:51 +07:00
..
README.md feat: add file upload endpoint 2025-10-11 00:08:51 +07:00
api.rest feat: remove unused endpoints 2025-10-09 23:48:25 +07:00

README.md

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:

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):

    curl -X POST http://localhost:3000/api/bootstrap/initial-key
    
  2. Create Project Key - Use master key to create project keys:

    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/upload
    • 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/upload POST API Key 100/hour Upload single image file
/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):

{
  "apiKey": "bnt_...",
  "type": "master",
  "name": "Initial Master Key",
  "expiresAt": null,
  "message": "IMPORTANT: Save this key securely. You will not see it again!"
}

Error (403):

{
  "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:

{
  "type": "master | project",
  "projectId": "required-for-project-keys",
  "name": "optional-friendly-name",
  "expiresInDays": 90
}

Response (201):

{
  "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):

{
  "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):

{
  "message": "API key revoked successfully",
  "keyId": "uuid"
}

Health Check

GET /health

Health check endpoint with server status.

Response:

{
  "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:

{
  "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:

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):

{
  "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):

{
  "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:

{
  "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:

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):

{
  "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):

{
  "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

Upload File

POST /api/upload

Upload a single image file to project storage.

Authentication: Project API key required (master keys not allowed) Rate Limit: 100 requests per hour per API key

Content-Type: multipart/form-data

Parameters:

Field Type Required Description
file file Yes Single image file (PNG, JPEG, JPG, WebP)
metadata JSON No Optional metadata (description, tags)

File Specifications:

  • Max file size: 5MB
  • Supported formats: PNG, JPEG, JPG, WebP
  • Max files per request: 1

Example Request:

curl -X POST http://localhost:3000/api/upload \
  -H "X-API-Key: bnt_your_project_key_here" \
  -F "file=@image.png" \
  -F 'metadata={"description":"Product photo","tags":["demo","test"]}'

Success Response (200):

{
  "success": true,
  "message": "File uploaded successfully",
  "data": {
    "filename": "image-1728561234567-a1b2c3.png",
    "originalName": "image.png",
    "path": "org-slug/project-slug/uploads/image-1728561234567-a1b2c3.png",
    "url": "http://localhost:3000/api/images/org-slug/project-slug/uploads/image-1728561234567-a1b2c3.png",
    "size": 123456,
    "contentType": "image/png",
    "uploadedAt": "2025-10-10T12:00:00.000Z"
  }
}

Error Response (400 - No file):

{
  "success": false,
  "message": "File upload failed",
  "error": "No file provided"
}

Error Response (400 - Invalid file type):

{
  "success": false,
  "message": "File validation failed",
  "error": "Unsupported file type: image/gif. Allowed: PNG, JPEG, WebP"
}

Error Response (400 - File too large):

{
  "success": false,
  "message": "File upload failed",
  "error": "File too large. Maximum size: 5MB"
}

Storage Details:

  • Files are stored in MinIO under: {orgSlug}/{projectSlug}/uploads/
  • Filenames are automatically made unique with timestamp and random suffix
  • Original filename is preserved in response
  • Uploaded files can be accessed via the returned URL

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:

{
  "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):

{
  "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):

{
  "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/upload, /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/upload, /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.