From a508ff9527fa0c640c4c52b71777d7a0e1c5cec3 Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Tue, 30 Dec 2025 01:13:08 +0700 Subject: [PATCH] feat: add docs draft --- .../src/app/docs/api/advanced/page.tsx | 448 ++++++++++++++++++ .../src/app/docs/api/generate/page.tsx | 352 ++++++++++++++ apps/landing/src/app/docs/api/images/page.tsx | 330 +++++++++++++ apps/landing/src/app/docs/api/live/page.tsx | 414 ++++++++++++++++ .../src/app/docs/api/text-to-image/page.tsx | 226 --------- apps/landing/src/app/docs/api/upload/page.tsx | 269 +++++++++++ .../app/docs/guides/authentication/page.tsx | 313 ------------ apps/landing/src/app/docs/page.tsx | 41 +- .../components/docs/layout/DocsSidebar.tsx | 30 +- 9 files changed, 1843 insertions(+), 580 deletions(-) create mode 100644 apps/landing/src/app/docs/api/advanced/page.tsx create mode 100644 apps/landing/src/app/docs/api/generate/page.tsx create mode 100644 apps/landing/src/app/docs/api/images/page.tsx create mode 100644 apps/landing/src/app/docs/api/live/page.tsx delete mode 100644 apps/landing/src/app/docs/api/text-to-image/page.tsx create mode 100644 apps/landing/src/app/docs/api/upload/page.tsx delete mode 100644 apps/landing/src/app/docs/guides/authentication/page.tsx diff --git a/apps/landing/src/app/docs/api/advanced/page.tsx b/apps/landing/src/app/docs/api/advanced/page.tsx new file mode 100644 index 0000000..63a64f7 --- /dev/null +++ b/apps/landing/src/app/docs/api/advanced/page.tsx @@ -0,0 +1,448 @@ +'use client'; + +/** + * API Reference: Advanced Generation + * + * Based on docs/api/image-generation-advanced.md + */ + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { Table } from '@/components/docs/shared/Table'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { + Hero, + SectionHeader, + InlineCode, + EndpointCard, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'reference-images', text: 'Reference Images', level: 2 }, + { id: 'alias-assignment', text: 'Alias Assignment', level: 2 }, + { id: 'alias-resolution', text: '3-Tier Alias Resolution', level: 2 }, + { id: 'flows', text: 'Generation Flows', level: 2 }, + { id: 'regeneration', text: 'Regeneration', level: 2 }, + { id: 'flow-management', text: 'Flow Management', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +const referenceLimits = [ + ['Max references', '3 images'], + ['Max file size', '5MB per image'], + ['Supported formats', 'PNG, JPEG, WebP'], +]; + +const aliasFormat = [ + ['Prefix', 'Must start with @'], + ['Characters', 'Alphanumeric, underscore, hyphen'], + ['Pattern', '@[a-zA-Z0-9_-]+'], + ['Max length', '50 characters'], + ['Examples', '@logo, @hero-bg, @image_1'], +]; + +const technicalAliases = [ + ['@last', 'Most recently generated image in flow'], + ['@first', 'First generated image in flow'], + ['@upload', 'Most recently uploaded image in flow'], +]; + +const flowIdBehavior = [ + ['undefined (not provided)', 'Auto-generate pendingFlowId, lazy creation'], + ['null (explicitly null)', 'No flow association'], + ['"uuid-string"', 'Use provided ID, create flow if doesn\'t exist'], +]; + +const regenerationTriggers = [ + ['prompt', 'Yes'], + ['aspectRatio', 'Yes'], + ['flowId', 'No (metadata only)'], + ['meta', 'No (metadata only)'], +]; + +export default function AdvancedGenerationPage() { + return ( + + {/* Hero Section */} + + + {/* Overview */} +
+ + Overview + +

+ The Advanced Generation API extends basic generation with powerful features for + production workflows: reference images for style guidance, aliases for human-readable + identifiers, and flows for organizing related generations. +

+ + Tip: For basic generation without these features, see the{' '} + Image Generation page. + +
+ + {/* Reference Images */} +
+ + Reference Images + +

+ Use existing images as style or content references for generation. +

+ + + Using References + +

+ Add referenceImages array to your generation request: +

+ + + +

+ References can be: +

+
    +
  • Project aliases: @logo, @brand-style
  • +
  • Flow aliases: @hero (with flowId context)
  • +
  • Technical aliases: @last, @first, @upload
  • +
  • Image UUIDs: 550e8400-e29b-41d4-a716-446655440000
  • +
+ + + Auto-Detection from Prompt + +

+ Aliases in the prompt are automatically detected and used as references: +

+ + + + + Reference Limits + + [ + constraint, + {limit}, + ])} + /> + + + {/* Alias Assignment */} +
+ + Alias Assignment + +

+ Assign aliases to generated images for easy referencing. +

+ + + Project-Scoped Alias + +

+ Use alias parameter to assign a project-wide alias: +

+ + + + + Flow-Scoped Alias + +

+ Use flowAlias parameter to assign a flow-specific alias: +

+ + + + + Alias Format + +
[ + rule, + {description}, + ])} + /> + +
+ + Override Behavior: When assigning an existing alias, the new image gets + the alias and the old image loses it. The old image is not deleted, just unlinked. + +
+ + + {/* 3-Tier Alias Resolution */} +
+ + 3-Tier Alias Resolution + +

+ Aliases are resolved in order of precedence: +

+ + + 1. Technical Aliases (Highest Priority) + +

+ Computed on-the-fly, require flow context: +

+
[ + {alias}, + returns, + ])} + /> + + + 2. Flow Aliases + +

+ Stored in flow's aliases JSONB field. + Different flows can have the same alias pointing to different images. +

+ + + 3. Project Aliases (Lowest Priority) + +

+ Stored in image's alias column. + Global across the project, unique per project. +

+ +
+ +
+ + + {/* Generation Flows */} +
+ + Generation Flows + +

+ Flows organize related generations into chains. +

+ + + Lazy Flow Creation + +

+ When flowId is not provided, a pending flow ID is generated. + The flow record is created when a second generation uses the same flowId or a flowAlias is assigned. +

+ + + Eager Flow Creation + +

+ When flowAlias is provided, the flow is created immediately. +

+ + + flowId Behavior + +
[ + {value}, + behavior, + ])} + /> + + + {/* Regeneration */} +
+ + Regeneration + + + + Regenerate Generation + + +

+ Recreate an image using the exact same parameters. The output image ID and URL are preserved. +

+ + + Update and Regenerate + + +

+ Modify parameters with smart regeneration: +

+ +
[ + {field}, + {triggers}, + ])} + /> + + + Flow Regenerate + + +

+ Regenerate the most recent generation in a flow. +

+ + + {/* Flow Management */} +
+ + Flow Management + + +
+
+ +

List all flows with pagination

+
+ +
+ +

Get flow with computed counts and aliases

+
+ +
+ +

List all generations in the flow

+
+ +
+ +

List all images in the flow (generated and uploaded)

+
+ +
+ +

Update flow aliases (merges with existing)

+
+ +
+ +

Delete flow with cascade behavior

+
+
+ +
+ + Cascade Delete: Deleting a flow hard-deletes all generations and images + without project aliases. Images with project aliases are kept but unlinked from the flow. + +
+
+ + ); +} diff --git a/apps/landing/src/app/docs/api/generate/page.tsx b/apps/landing/src/app/docs/api/generate/page.tsx new file mode 100644 index 0000000..dc2db7c --- /dev/null +++ b/apps/landing/src/app/docs/api/generate/page.tsx @@ -0,0 +1,352 @@ +'use client'; + +/** + * API Reference: Image Generation + * + * Based on docs/api/image-generation.md + */ + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { Table } from '@/components/docs/shared/Table'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { InteractiveAPIWidget } from '@/components/docs/blocks/InteractiveAPIWidget'; +import { + Hero, + SectionHeader, + InlineCode, + EndpointCard, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'endpoint', text: 'Create Generation', level: 2 }, + { id: 'parameters', text: 'Parameters', level: 2 }, + { id: 'aspect-ratios', text: 'Aspect Ratios', level: 2 }, + { id: 'prompt-enhancement', text: 'Prompt Enhancement', level: 2 }, + { id: 'generation-status', text: 'Generation Status', level: 2 }, + { id: 'response', text: 'Response Format', level: 2 }, + { id: 'error-codes', text: 'Error Codes', level: 2 }, + { id: 'interactive', text: 'Try It Live', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +const parameters = [ + { name: 'prompt', type: 'string', required: true, description: 'Text description of the image to generate' }, + { name: 'aspectRatio', type: 'string', required: false, default: '"1:1"', description: 'Image aspect ratio (1:1, 16:9, 9:16, 3:2, 21:9)' }, + { name: 'autoEnhance', type: 'boolean', required: false, default: 'true', description: 'Enable AI prompt enhancement for better results' }, + { name: 'meta', type: 'object', required: false, default: '{}', description: 'Custom metadata to store with generation' }, +]; + +const aspectRatios = [ + ['1:1', 'Square images, social media posts, profile pictures'], + ['16:9', 'Landscape, hero banners, video thumbnails'], + ['9:16', 'Portrait, mobile screens, stories'], + ['3:2', 'Photography standard, print'], + ['21:9', 'Ultra-wide banners, cinematic'], +]; + +const statuses = [ + ['pending', 'Generation created, waiting to start'], + ['processing', 'AI is generating the image'], + ['success', 'Image generated successfully'], + ['failed', 'Generation failed (see errorMessage)'], +]; + +const errorCodes = [ + ['400', 'VALIDATION_ERROR', 'Invalid parameters in the request body'], + ['401', 'UNAUTHORIZED', 'Missing or invalid API key in X-API-Key header'], + ['404', 'GENERATION_NOT_FOUND', 'Generation does not exist'], + ['429', 'RATE_LIMIT_EXCEEDED', 'Too many requests (100/hour limit)'], + ['500', 'GENERATION_FAILED', 'AI generation failed'], +]; + +export default function ImageGenerationPage() { + return ( + + {/* Hero Section */} + + + {/* Overview */} +
+ + Overview + +

+ The Image Generation API allows you to create AI-generated images from natural language descriptions. + Powered by advanced AI models, it produces high-quality images optimized for your specified requirements. +

+ + Tip: Enable autoEnhance (on by default) + to let AI improve your prompts for better image quality. + +
+ + {/* Endpoint */} +
+ + Create Generation + + +

+ Requires X-API-Key header with your Project Key. +

+
+ + {/* Parameters */} +
+ + Parameters + +

+ All parameters should be sent in the request body as JSON. +

+ +
[ + {param.name}, + {param.type}, + + {param.required ? 'Yes' : 'No'} + , + param.default ? {param.default} : -, + param.description, + ])} + /> + +
+ +
+ + + {/* Aspect Ratios */} +
+ + Aspect Ratios + +

+ Supported aspect ratios for image generation: +

+ +
[ + {ratio}, + useCase, + ])} + /> + + + {/* Prompt Enhancement */} +
+ + Prompt Enhancement + +

+ By default, prompts are automatically enhanced by AI to produce better results. +

+ + + How It Works + +

+ When autoEnhance: true (default): +

+
    +
  • Your original prompt is preserved in originalPrompt
  • +
  • AI enhances it with style details, lighting, and composition
  • +
  • The enhanced version is stored in prompt and used for generation
  • +
+ +

+ When autoEnhance: false: +

+
    +
  • Both prompt and originalPrompt contain your original text
  • +
  • No AI enhancement is applied
  • +
+ + + Enhancement Templates (Roadmap): Template selection for enhancement styles + (photorealistic, illustration, minimalist, etc.) is planned for a future release. + Currently all enhanced prompts use the default general style. + + +
+ +
+
+ + {/* Generation Status */} +
+ + Generation Status + +

+ Generations go through these status stages: +

+ +
[ + {status}, + description, + ])} + /> + +

+ Poll the generation endpoint to check status: +

+ +

+ When status: "success", the outputImageId field + contains the generated image ID. +

+ + + {/* Response */} +
+ + Response Format + +

+ On success, the API returns a JSON object containing the generation details and output image. +

+ + + + + Note: The image URL uses the UUID as filename with no extension. + Content-Type is stored in object metadata. + +
+ + {/* Error Codes */} +
+ + Error Codes + +

+ The API uses standard HTTP status codes and returns descriptive error messages. +

+ +
[ + {status}, + {code}, + description, + ])} + /> + +
+ + Rate Limits: Project API keys are limited to 100 requests per hour. + Check X-RateLimit-Remaining header for current usage. + +
+ + + {/* Interactive Widget */} +
+ + Try It Live + +

+ Test the API directly from this page. Enter your API key and customize the parameters below. +

+ + +
+ + ); +} diff --git a/apps/landing/src/app/docs/api/images/page.tsx b/apps/landing/src/app/docs/api/images/page.tsx new file mode 100644 index 0000000..bd2bf99 --- /dev/null +++ b/apps/landing/src/app/docs/api/images/page.tsx @@ -0,0 +1,330 @@ +'use client'; + +/** + * API Reference: Image Management + * + * Based on docs/api/images-upload.md (CRUD sections) + */ + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { Table } from '@/components/docs/shared/Table'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { + Hero, + SectionHeader, + InlineCode, + EndpointCard, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'list-images', text: 'List Images', level: 2 }, + { id: 'get-image', text: 'Get Image', level: 2 }, + { id: 'update-metadata', text: 'Update Metadata', level: 2 }, + { id: 'assign-alias', text: 'Assign Alias', level: 2 }, + { id: 'delete-image', text: 'Delete Image', level: 2 }, + { id: 'response-fields', text: 'Response Fields', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +const listQueryParams = [ + { name: 'flowId', type: 'string', default: '-', description: 'Filter by flow UUID' }, + { name: 'source', type: 'string', default: '-', description: 'Filter by source: generated, uploaded' }, + { name: 'alias', type: 'string', default: '-', description: 'Filter by exact alias match' }, + { name: 'limit', type: 'number', default: '20', description: 'Results per page (max: 100)' }, + { name: 'offset', type: 'number', default: '0', description: 'Pagination offset' }, + { name: 'includeDeleted', type: 'boolean', default: 'false', description: 'Include soft-deleted records' }, +]; + +const responseFields = [ + ['id', 'string', 'Image UUID (same as filename in storage)'], + ['projectId', 'string', 'Project UUID'], + ['flowId', 'string', 'Associated flow UUID (null if none)'], + ['storageUrl', 'string', 'CDN URL for direct access'], + ['mimeType', 'string', 'Image MIME type'], + ['fileSize', 'number', 'File size in bytes'], + ['width', 'number', 'Image width in pixels'], + ['height', 'number', 'Image height in pixels'], + ['source', 'string', '"generated" or "uploaded"'], + ['alias', 'string', 'Project-scoped alias (null if none)'], + ['focalPoint', 'object', '{ x, y } coordinates (0.0-1.0)'], + ['meta', 'object', 'Custom metadata'], + ['createdAt', 'string', 'ISO timestamp'], + ['updatedAt', 'string', 'ISO timestamp'], +]; + +export default function ImageManagementPage() { + return ( + + {/* Hero Section */} + + + {/* Overview */} +
+ + Overview + +

+ The Image Management API provides CRUD operations for images in your project. + Access images by UUID or alias, update metadata, and manage aliases for easy reference. +

+ + Tip: Use aliases like @hero for human-readable + references instead of UUIDs. + +
+ + {/* List Images */} +
+ + List Images + + + + + Query Parameters + +
[ + {param.name}, + {param.type}, + param.default === '-' ? - : {param.default}, + param.description, + ])} + /> + +
+ +
+ + + {/* Get Image */} +
+ + Get Image + + +

+ Retrieve a single image by UUID or alias. +

+ + + +
+ + Alias Resolution: When using aliases with flowId, + the system checks flow aliases first, then falls back to project aliases. + +
+
+ + {/* Update Metadata */} +
+ + Update Metadata + + +

+ Update image metadata including focal point and custom data. +

+ + + +

+ Note: Alias assignment has its own dedicated endpoint. +

+
+ + {/* Assign Alias */} +
+ + Assign Alias + + +

+ Assign or remove a project-scoped alias from an image. +

+ + + +
+ + Override Behavior: If another image has the alias, it loses the alias. + The target image gets the alias. The old image is preserved, just unlinked. + +
+
+ + {/* Delete Image */} +
+ + Delete Image + + +

+ Permanently delete an image and its storage file. +

+ + + +
+ + Warning: This action is irreversible. The image record and storage file + are permanently deleted. Related generations will have their outputImageId set to null. + +
+
+ + {/* Response Fields */} +
+ + Response Fields + +

+ Complete list of fields returned in image responses: +

+ +
[ + {field}, + {type}, + description, + ])} + /> + + + Accessing Images + +

+ Use storageUrl for direct CDN access: +

+ + + + + +`} + language="html" + filename="Usage Examples" + /> + + + Performance: UUID URLs are served directly from CDN. + Alias URLs require API resolution but enable dynamic reassignment. + + + + ); +} diff --git a/apps/landing/src/app/docs/api/live/page.tsx b/apps/landing/src/app/docs/api/live/page.tsx new file mode 100644 index 0000000..d73d222 --- /dev/null +++ b/apps/landing/src/app/docs/api/live/page.tsx @@ -0,0 +1,414 @@ +'use client'; + +/** + * API Reference: Live URLs & CDN + * + * Based on docs/api/live-url.md + */ + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { Table } from '@/components/docs/shared/Table'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { + Hero, + SectionHeader, + InlineCode, + EndpointCard, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'url-architecture', text: 'URL Architecture', level: 2 }, + { id: 'cdn-serving', text: 'CDN Image Serving', level: 2 }, + { id: 'live-generation', text: 'Live URL Generation', level: 2 }, + { id: 'cache-behavior', text: 'Cache Behavior', level: 2 }, + { id: 'rate-limiting', text: 'IP Rate Limiting', level: 2 }, + { id: 'scope-management', text: 'Scope Management', level: 2 }, + { id: 'use-cases', text: 'Use Cases', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +const urlPatterns = [ + ['/{org}/{proj}/img/{uuid}', 'Direct image by UUID', 'Caddy → MinIO (public)'], + ['/{org}/{proj}/img/@{alias}', 'Image by alias', 'Caddy → API → MinIO'], + ['/{org}/{proj}/live/{scope}?prompt=...', 'Live generation', 'Caddy → API → MinIO'], +]; + +const liveQueryParams = [ + { name: 'prompt', type: 'string', required: true, default: '-', description: 'Image description' }, + { name: 'aspectRatio', type: 'string', required: false, default: '"1:1"', description: 'Aspect ratio' }, + { name: 'autoEnhance', type: 'boolean', required: false, default: 'true', description: 'Enable prompt enhancement' }, +]; + +const cacheHitHeaders = [ + ['Content-Type', 'image/jpeg'], + ['Cache-Control', 'public, max-age=31536000'], + ['X-Cache-Status', 'HIT'], + ['X-Scope', 'Scope identifier'], + ['X-Image-Id', 'Image UUID'], +]; + +const cacheMissHeaders = [ + ['Content-Type', 'image/jpeg'], + ['Cache-Control', 'public, max-age=31536000'], + ['X-Cache-Status', 'MISS'], + ['X-Scope', 'Scope identifier'], + ['X-Generation-Id', 'Generation UUID'], + ['X-Image-Id', 'Image UUID'], + ['X-RateLimit-Limit', '10'], + ['X-RateLimit-Remaining', 'Remaining requests'], + ['X-RateLimit-Reset', 'Seconds until reset'], +]; + +const rateLimits = [ + ['New generations', '10 per hour per IP'], + ['Cache hits', 'Unlimited'], +]; + +const scopeParams = [ + { name: 'slug', type: 'string', required: true, default: '-', description: 'Unique identifier' }, + { name: 'allowNewGenerations', type: 'boolean', required: false, default: 'true', description: 'Allow new generations' }, + { name: 'newGenerationsLimit', type: 'number', required: false, default: '30', description: 'Max generations in scope' }, + { name: 'meta', type: 'object', required: false, default: '{}', description: 'Custom metadata' }, +]; + +const errorCodes = [ + ['400', 'SCOPE_INVALID_FORMAT', 'Invalid scope slug format'], + ['403', 'SCOPE_CREATION_DISABLED', 'New scope creation not allowed'], + ['404', 'ORG_NOT_FOUND', 'Organization not found'], + ['404', 'PROJECT_NOT_FOUND', 'Project not found'], + ['404', 'SCOPE_NOT_FOUND', 'Scope does not exist'], + ['409', 'SCOPE_ALREADY_EXISTS', 'Scope slug already in use'], + ['429', 'IP_RATE_LIMIT_EXCEEDED', 'IP rate limit (10/hour) exceeded'], + ['429', 'SCOPE_GENERATION_LIMIT_EXCEEDED', 'Scope limit reached'], +]; + +export default function LiveUrlsPage() { + return ( + + {/* Hero Section */} + + + {/* Overview */} +
+ + Overview + +

+ Live URLs provide a simple way to generate images on-demand using URL parameters. + Images are cached automatically, so repeated requests return instantly without counting + toward rate limits. +

+ + No API Key Required: Live URLs are public endpoints. Rate limiting + is done by IP address instead of API key. + +
+ + {/* URL Architecture */} +
+ + URL Architecture + +

+ All images are accessible via CDN at https://cdn.banatie.app: +

+ +
[ + {pattern}, + description, + {routing}, + ])} + /> + +
+ +
+ + + {/* CDN Image Serving */} +
+ + CDN Image Serving + + +

+ Serve images by UUID or project-scoped alias. No authentication required. +

+ + + + + Performance: UUID requests are served directly from MinIO with edge caching. + Alias requests require API resolution but enable dynamic reassignment. + +
+ + {/* Live URL Generation */} +
+ + Live URL Generation + + +

+ Generate images on-demand via URL parameters. No authentication required. +

+ + + Query Parameters + +
[ + {param.name}, + {param.type}, + + {param.required ? 'Yes' : 'No'} + , + param.default === '-' ? - : {param.default}, + param.description, + ])} + /> + +
+ +`} + language="html" + filename="Example Usage" + /> +
+ + + {/* Cache Behavior */} +
+ + Cache Behavior + + + + Cache HIT + +

+ Image exists in cache - returns instantly without rate limit check. +

+
[ + {header}, + {value}, + ])} + /> + + + Cache MISS + +

+ New generation - generates image, stores in cache, counts toward rate limit. +

+
[ + {header}, + {value}, + ])} + /> + +
+ + Cache Key: Computed from{' '} + projectId + scope + prompt + aspectRatio + autoEnhance + +
+ + + {/* IP Rate Limiting */} +
+ + IP Rate Limiting + +

+ Live URLs are rate limited by IP address: +

+ +
[ + limit, + {value}, + ])} + /> + +
+ + Important: Only cache MISS (new generations) count toward the limit. + Cache HIT requests are unlimited. + +
+ + + {/* Scope Management */} +
+ + Scope Management + +

+ Scopes organize live URL generation budgets. Scope endpoints require Project Key authentication. +

+ + + Create Scope + + + +
[ + {param.name}, + {param.type}, + + {param.required ? 'Yes' : 'No'} + , + param.default === '-' ? - : {param.default}, + param.description, + ])} + /> + + + Lazy Scope Creation + +

+ Scopes are auto-created on first live URL request if project.allowNewLiveScopes = true. +

+ + + Scope Endpoints + +
+
+ +

List all scopes with pagination

+
+
+ +

Get scope with statistics

+
+
+ +

Update scope settings

+
+
+ +

Regenerate scope images

+
+
+ +

Delete scope (cascades to images)

+
+
+ +
+ + Delete Warning: Deleting a scope permanently removes all cached images. + Aliased images may be kept based on alias protection rules. + +
+ + + {/* Use Cases */} +
+ + Use Cases + + + + Dynamic Hero Images + + `} + language="html" + filename="Hero Image" + /> +

First load generates, subsequent loads are cached.

+ + + Product Placeholders + + `} + language="html" + filename="Product Placeholder" + /> + + + Blog Post Images + + `} + language="html" + filename="Blog Image" + /> +
+ + ); +} diff --git a/apps/landing/src/app/docs/api/text-to-image/page.tsx b/apps/landing/src/app/docs/api/text-to-image/page.tsx deleted file mode 100644 index 0d5fb8a..0000000 --- a/apps/landing/src/app/docs/api/text-to-image/page.tsx +++ /dev/null @@ -1,226 +0,0 @@ -'use client'; - -/** - * API Reference: Text to Image - * - * Refactored to use DocPage component for consistent layout - * Layout handles SubsectionNav and Left Sidebar - * DocPage handles Breadcrumb, Article structure, Next Steps, and TOC - * This page provides only the content (Hero + sections) - */ - -import { TipBox } from '@/components/docs/shared/TipBox'; -import { Table } from '@/components/docs/shared/Table'; -import { CodeBlock } from '@/components/docs/shared/CodeBlock'; -import { DocPage } from '@/components/docs/layout/DocPage'; -import { InteractiveAPIWidget } from '@/components/docs/blocks/InteractiveAPIWidget'; -import { - Hero, - SectionHeader, - InlineCode, - EndpointCard, -} from '@/components/docs/blocks'; - -const tocItems = [ - { id: 'overview', text: 'Overview', level: 2 }, - { id: 'endpoint', text: 'Endpoint', level: 2 }, - { id: 'parameters', text: 'Parameters', level: 2 }, - { id: 'response', text: 'Response', level: 2 }, - { id: 'error-codes', text: 'Error Codes', level: 2 }, - { id: 'interactive', text: 'Try It Live', level: 2 }, - { id: 'next-steps', text: 'Next Steps', level: 2 }, -]; - -const parameters = [ - { name: 'prompt', type: 'string', required: true, description: 'Text description of the image to generate' }, - { name: 'filename', type: 'string', required: false, description: 'Output filename (without extension)' }, - { name: 'aspectRatio', type: 'string', required: false, description: 'Image aspect ratio: "1:1", "16:9", "9:16", "4:3"' }, - { name: 'autoEnhance', type: 'boolean', required: false, description: 'Enable AI prompt enhancement for better results' }, -]; - -export default function TextToImageAPIPage() { - return ( - - - {/* Hero Section */} - - - {/* Overview */} -
- - Overview - -

- The Text to Image endpoint allows you to generate images from natural language descriptions. - Powered by Google Gemini 2.5 Flash and Imagen 4.0, it produces photorealistic images - optimized for your specified requirements. -

- - Tip: Enable autoEnhance - to let AI improve your prompts for better image quality. - -
- - {/* Endpoint */} -
- - Endpoint - - -
- - {/* Parameters */} -
- - Parameters - -

- All parameters should be sent in the request body as JSON. -

- -
[ - {param.name}, - {param.type}, - - {param.required ? 'Yes' : 'No'} - , - param.description, - ])} - /> - -
- - Default Values: If not specified, filename is - auto-generated, aspectRatio defaults - to "1:1", and autoEnhance is false. - -
- - - {/* Response */} -
- - Response - -

- On success, the API returns a JSON object containing the generated image URL and metadata. -

- - -
- - {/* Error Codes */} -
- - Error Codes - -

- The API uses standard HTTP status codes and returns descriptive error messages. -

- -
400, - 'Bad Request', - 'Missing or invalid parameters in the request body', - ], - [ - 401, - 'Unauthorized', - 'Missing or invalid API key in X-API-Key header', - ], - [ - 429, - 'Rate Limit', - 'Too many requests. Check rate limit headers for retry timing', - ], - [ - 500, - 'Server Error', - 'Internal server error. Contact support if persists', - ], - ]} - /> - -
- - Rate Limits: Project API keys are limited to 100 requests per hour. - Upgrade your plan for higher limits. - -
- - - {/* Interactive Widget */} -
- - Try It Live - -

- Test the API directly from this page. Enter your API key and customize the parameters below. -

- - -
- - - ); -} diff --git a/apps/landing/src/app/docs/api/upload/page.tsx b/apps/landing/src/app/docs/api/upload/page.tsx new file mode 100644 index 0000000..81e5c4b --- /dev/null +++ b/apps/landing/src/app/docs/api/upload/page.tsx @@ -0,0 +1,269 @@ +'use client'; + +/** + * API Reference: Image Upload + * + * Based on docs/api/images-upload.md (upload section) + */ + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { Table } from '@/components/docs/shared/Table'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { + Hero, + SectionHeader, + InlineCode, + EndpointCard, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'endpoint', text: 'Upload Endpoint', level: 2 }, + { id: 'parameters', text: 'Form Parameters', level: 2 }, + { id: 'constraints', text: 'File Constraints', level: 2 }, + { id: 'flow-association', text: 'Flow Association', level: 2 }, + { id: 'response', text: 'Response Format', level: 2 }, + { id: 'error-codes', text: 'Error Codes', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +const formParameters = [ + { name: 'file', type: 'file', required: true, description: 'Image file (PNG, JPEG, WebP)' }, + { name: 'alias', type: 'string', required: false, description: 'Project-scoped alias (e.g., @logo)' }, + { name: 'flowId', type: 'string', required: false, description: 'Flow UUID to associate with' }, + { name: 'flowAlias', type: 'string', required: false, description: 'Flow-scoped alias (requires flowId)' }, + { name: 'meta', type: 'string', required: false, description: 'JSON string with custom metadata' }, +]; + +const fileConstraints = [ + ['Max file size', '5MB'], + ['Supported formats', 'PNG, JPEG, JPG, WebP'], + ['MIME types', 'image/png, image/jpeg, image/webp'], +]; + +const flowIdBehavior = [ + ['Not provided', 'Auto-generate pendingFlowId, lazy flow creation'], + ['null', 'No flow association'], + ['"uuid"', 'Associate with specified flow'], +]; + +const errorCodes = [ + ['400', 'VALIDATION_ERROR', 'Invalid parameters'], + ['400', 'FILE_TOO_LARGE', 'File exceeds 5MB limit'], + ['400', 'UNSUPPORTED_FILE_TYPE', 'Not PNG, JPEG, or WebP'], + ['400', 'ALIAS_FORMAT_CHECK', 'Alias must start with @'], + ['401', 'UNAUTHORIZED', 'Missing or invalid API key'], +]; + +export default function ImageUploadPage() { + return ( + + {/* Hero Section */} + + + {/* Overview */} +
+ + Overview + +

+ The Upload API allows you to upload images to your project. Uploaded images can be used as + references for image-to-image generation, assigned aliases for easy access, or stored as + standalone assets. +

+ + Tip: Use aliases like @logo to reference + uploaded images by name instead of UUID. + +
+ + {/* Endpoint */} +
+ + Upload Endpoint + + +

+ Requires X-API-Key header with your Project Key. + Content-Type must be multipart/form-data. +

+
+ + {/* Parameters */} +
+ + Form Parameters + +

+ Send parameters as multipart/form-data: +

+ +
[ + {param.name}, + {param.type}, + + {param.required ? 'Yes' : 'No'} + , + param.description, + ])} + /> + +
+ +
+ + + {/* File Constraints */} +
+ + File Constraints + + +
[ + constraint, + {limit}, + ])} + /> + +
+ + File Size: Files larger than 5MB will be rejected with a 400 error. + Compress images before uploading if needed. + +
+ + + {/* Flow Association */} +
+ + Flow Association + +

+ Images can be associated with generation flows for organized workflows. + The flowId parameter controls this behavior: +

+ +
[ + {value}, + behavior, + ])} + /> + +
+ +
+ + + {/* Response */} +
+ + Response Format + +

+ On success, the API returns a JSON object containing the uploaded image details. +

+ + + + + Note: The id field equals the filename in storage (UUID). + Original filename is preserved in object metadata. + +
+ + {/* Error Codes */} +
+ + Error Codes + +

+ The API uses standard HTTP status codes and returns descriptive error messages. +

+ +
[ + {status}, + {code}, + description, + ])} + /> + + + ); +} diff --git a/apps/landing/src/app/docs/guides/authentication/page.tsx b/apps/landing/src/app/docs/guides/authentication/page.tsx deleted file mode 100644 index e05dac7..0000000 --- a/apps/landing/src/app/docs/guides/authentication/page.tsx +++ /dev/null @@ -1,313 +0,0 @@ -'use client'; - -/** - * Authentication Guide - * - * Refactored to use DocPage component for consistent layout - * Layout handles SubsectionNav and Left Sidebar - * DocPage handles Breadcrumb, Article structure, Next Steps, and TOC - * This page provides only the content (Hero + sections) - */ - -import { TipBox } from '@/components/docs/shared/TipBox'; -import { Table } from '@/components/docs/shared/Table'; -import { CodeBlock } from '@/components/docs/shared/CodeBlock'; -import { DocPage } from '@/components/docs/layout/DocPage'; -import { - Hero, - SectionHeader, - InlineCode, -} from '@/components/docs/blocks'; - -const tocItems = [ - { id: 'overview', text: 'Overview', level: 2 }, - { id: 'api-keys', text: 'API Keys', level: 2 }, - { id: 'key-types', text: 'Key Types', level: 3 }, - { id: 'creating-keys', text: 'Creating Keys', level: 3 }, - { id: 'using-keys', text: 'Using API Keys', level: 2 }, - { id: 'rate-limits', text: 'Rate Limits', level: 2 }, - { id: 'security', text: 'Security Best Practices', level: 2 }, - { id: 'next-steps', text: 'Next Steps', level: 2 }, -]; - -export default function AuthenticationGuidePage() { - return ( - - - {/* Hero Section */} - - - {/* Overview */} -
- - Overview - -

- Banatie uses API keys to authenticate requests. All API endpoints require authentication - via the X-API-Key header. - API keys are tied to organizations and projects, providing fine-grained access control. -

- - - Quick Start: New to API authentication? Check out our{' '} - - Getting Started guide - {' '} - for a step-by-step walkthrough. - -
- - {/* API Keys */} -
- - API Keys - - -
- - Key Types - -

- Banatie supports two types of API keys, each with different permissions and use cases: -

- -
Master Key, - 'Full admin access, can create/revoke keys', - Never expires, - 'Server-side admin operations, key management', - ], - [ - Project Key, - 'Image generation only', - 90 days, - 'Application integration, API requests', - ], - ]} - /> - -
- - Master Key Security: Master keys have full - administrative access and never expire. Store them securely in encrypted vaults or - secret managers. Never expose master keys in client-side code, logs, or version control. - Use project keys for application integration whenever possible. - -
- - -
- - Creating Keys - -

- For first-time setup, use the bootstrap endpoint to create your initial master key: -

- - - -
-

- Once you have a master key, you can create project keys for your applications: -

- - -
-
- - - {/* Using API Keys */} -
- - Using API Keys - -

- Include your API key in the X-API-Key header - with every request: -

- - - -
- - Environment Variables: Store API keys in environment variables, not - hardcoded in your application. Example:{' '} - BANATIE_API_KEY - -
-
- - {/* Rate Limits */} -
- - Rate Limits - -

- API keys are subject to rate limits to ensure fair usage and system stability. Limits - vary by key type and plan tier: -

- -
Master Key, - Unlimited, - 'N/A', - 'N/A', - ], - [ - Project Key (Free), - 100 requests/hour, - '1 hour rolling', - Yes, - ], - [ - Project Key (Pro), - 1,000 requests/hour, - '1 hour rolling', - Yes, - ], - ]} - /> - -
-

- When you exceed rate limits, the API returns a 429 Too Many Requests status. - Check the response headers for retry timing: -

- - -
- - - {/* Security Best Practices */} -
- - Security Best Practices - - - - Critical Security Guidelines: -
    -
  • Never commit API keys to version control systems (Git, SVN, etc.)
  • -
  • Store keys in environment variables or secret management services
  • -
  • Use project keys in applications, reserve master keys for admin operations
  • -
  • Rotate keys regularly, especially after team member changes
  • -
  • Implement server-side API calls for production applications
  • -
  • Monitor API key usage in your dashboard for suspicious activity
  • -
-
- -
-

Key Rotation Example

- -
-
- - - ); -} diff --git a/apps/landing/src/app/docs/page.tsx b/apps/landing/src/app/docs/page.tsx index a1c3e0b..7ff1881 100644 --- a/apps/landing/src/app/docs/page.tsx +++ b/apps/landing/src/app/docs/page.tsx @@ -40,15 +40,15 @@ export default function GettingStartedPage() { 'Now that you have generated your first image, explore these resources to build more advanced integrations:', links: [ { - href: '/docs/api/text-to-image', - title: 'API Reference', + href: '/docs/api/generate', + title: 'Image Generation', description: 'Explore all available endpoints, parameters, and response formats.', accent: 'primary', }, { - href: '/docs/guides/authentication', - title: 'Authentication Guide', - description: 'Learn about API keys, rate limits, and security best practices.', + href: '/docs/api/live', + title: 'Live URLs & CDN', + description: 'Generate images on-demand via URL parameters with automatic caching.', accent: 'secondary', }, ], @@ -67,9 +67,8 @@ export default function GettingStartedPage() { Introduction

- Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini - 2.5 Flash and Imagen 4.0, it transforms text prompts and reference images into - production-ready visuals. + Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini, + it transforms text prompts and reference images into production-ready visuals.

Whether you are building a content creation platform, e-commerce site, or creative tool, @@ -135,7 +134,7 @@ go get github.com/banatie/sdk-go`} Expected Response:

{ - const [expandedSections, setExpandedSections] = useState(['API Reference', 'Guides']); + const [expandedSections, setExpandedSections] = useState(['API Reference']); const toggleSection = (label: string) => { setExpandedSections((prev) =>