From 8e315ffe01b6973aaf17b392997c31e82344de1e Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Wed, 31 Dec 2025 01:28:10 +0700 Subject: [PATCH 1/8] doc: save task --- documentation-section-task.md | 606 ++++++++++++++++++++++++++++++++++ 1 file changed, 606 insertions(+) create mode 100644 documentation-section-task.md diff --git a/documentation-section-task.md b/documentation-section-task.md new file mode 100644 index 0000000..7829e50 --- /dev/null +++ b/documentation-section-task.md @@ -0,0 +1,606 @@ +# Banatie Documentation — Full Specification for Claude Code + +**Date:** December 30, 2025 +**Purpose:** Complete specification for generating documentation pages +**Source of Truth:** `/docs/api/*.md` in banatie-service repository +**Target:** `/apps/landing/src/app/docs/` + +--- + +## Documentation Spirit & Voice + +**This is critical. Every page must follow this approach:** + +### Tone +- **Technical but approachable** — developers respect precision, but don't want to read a manual +- **Confident, not arrogant** — we know our product works, no need to oversell +- **Direct** — say what you mean, no fluff, no filler phrases +- **Second person** — "you", "your", not "the user" or "one" + +### Content Philosophy +- **"Easy and simple" is the vibe** — everything should feel lightweight +- **Positive statements over negatives** — say what we DO, not what we don't +- **Show, don't tell** — code examples over explanations +- **One request, one result** — emphasize simplicity of the flow +- **Production-ready** — everything we deliver is ready to ship, not a prototype + +### What to Avoid +- Filler phrases ("In this section we will discuss...") +- Marketing speak ("revolutionary", "game-changing", "cutting-edge") +- Unnecessary warnings and caveats +- Over-explaining simple concepts +- Walls of text without visual breaks + +### Visual Variety +Use callouts, tables, code blocks liberally. Break up text. Make pages scannable. + +--- + +## URL Structure (Final, SEO-Critical) + +``` +/docs # Getting Started +/docs/generation # Image Generation (main guide) +/docs/images # Working with Images +/docs/live-urls # Live URL Generation +/docs/authentication # API Keys & Auth (after live-urls) +/docs/api # API Reference Overview +/docs/api/generations # Generations endpoints +/docs/api/images # Images endpoints +/docs/api/flows # Flows endpoints +/docs/api/live-scopes # Live Scopes endpoints +``` + +**10 pages total.** URLs are permanent — do not change after deployment. + +--- + +## Sidebar Navigation + +Two-level navigation: + +``` +Getting Started → /docs +Image Generation → /docs/generation +Working with Images → /docs/images +Live URLs → /docs/live-urls +Authentication → /docs/authentication +API Reference → /docs/api (expandable group) + ├─ Overview → /docs/api + ├─ Generations → /docs/api/generations + ├─ Images → /docs/api/images + ├─ Flows → /docs/api/flows + └─ Live Scopes → /docs/api/live-scopes +``` + +"API Reference" section is collapsible/expandable in sidebar. + +--- + +## Design System + +Use existing components from the landing app. Key elements: + +- **Code blocks** with syntax highlighting and copy button +- **Tables** for parameters, status codes, response fields +- **Callout blocks:** + - 💡 **Tip** — helpful hints, pro tips + - ⚠️ **Warning** — important cautions + - 📝 **Note** — additional context + - 🔒 **Security** — auth/security related +- **Response blocks** with status badges +- **Card links** for navigation to related pages +- **Breadcrumbs** for orientation + +**Visual variety is important** — break up walls of text with callouts, tables, code examples. + +--- + +## Cross-Linking Strategy + +Every guide page should link to corresponding API Reference section. +Every API Reference page should link back to the guide for context. + +Examples: +- `/docs/generation` → "See full endpoint details in [API Reference: Generations](/docs/api/generations)" +- `/docs/api/generations` → "For concepts and examples, see [Image Generation guide](/docs/generation)" + +--- + +## Page Specifications + +--- + +### Page 1: `/docs` — Getting Started + +**SEO Title:** "Getting Started with Banatie API | AI Image Generation" +**Meta Description:** "Generate your first AI image in a few simple steps. REST API for production-ready image assets via CDN." + +**Purpose:** First-time visitor lands here. Show them the value immediately. + +**CONTENT — USE EXACTLY AS WRITTEN:** + +```markdown +# Get Started + +Generate your first AI image in a few simple steps. + +## What is Banatie? + +Banatie is an image generation API for developers. Send a text prompt, get a production-ready image delivered via CDN. + +Simple REST API. Optimized AI models that deliver consistent results. Images ready for production use immediately. + +## Your First Image + +Once you have your API key, generate an image with a single request: + +```bash +curl -X POST https://api.banatie.app/api/v1/generations \ + -H "Content-Type: application/json" \ + -H "X-API-Key: YOUR_API_KEY" \ + -d '{"prompt": "a friendly robot waving hello"}' +``` + +That's it. The response contains your image: + +```json +{ + "success": true, + "data": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "status": "success", + "outputImage": { + "storageUrl": "https://cdn.banatie.app/my-org/my-project/img/8a3b2c1d-4e5f-6789-abcd-ef0123456789", + "width": 1792, + "height": 1008 + } + } +} +``` + +Open `storageUrl` in your browser — there's your robot. + +## Production Ready + +The image URL is permanent and served via global CDN. What this means for you: + +- **Fast access** — images load in milliseconds +- **Edge cached** — served from locations closest to your users +- **Global distribution** — works fast everywhere in the world + +One request. Production-ready result. Drop the URL into your app and ship. + +## Live URLs + +Want to skip the API call entirely? + +Generate images directly from a URL: + +``` +https://cdn.banatie.app/my-org/my-project/live/demo?prompt=a+friendly+robot+waving+hello +``` + +Put this in an `` tag. First request generates the image, all subsequent requests serve it from cache instantly. + +Perfect for placeholders, dynamic content, and rapid prototyping. + +→ **[Learn more about Live URLs](/docs/live-urls)** + +## Get Your API Key + +We're currently in early access. API keys are issued personally. + +**To request access:** +1. Go to [banatie.app](https://banatie.app) +2. Enter your email in the signup form +3. We'll send your API key within 24 hours + +## Next Steps + +- **[Image Generation](/docs/generation)** — Aspect ratios, prompt templates, using references +- **[Working with Images](/docs/images)** — Upload your own, organize with aliases +- **[Live URLs](/docs/live-urls)** — Generate images directly from URL parameters +- **[API Reference](/docs/api)** — Full endpoint documentation +``` + +--- + +### Page 2: `/docs/generation` — Image Generation + +**SEO Title:** "Image Generation | Banatie API Docs" +**Meta Description:** "Generate AI images from text prompts. Supports references, prompt templates, and chaining." + +**Sections:** + +1. **Basic Generation** + - POST /api/v1/generations + - Simple example: just prompt + - Response with status, outputImage, storageUrl + - Emphasize: one request → image ready + +2. **Aspect Ratios** + - Table of supported ratios with use cases + - 1:1, 16:9, 9:16, 3:2, 21:9 + +3. **Prompt Templates** + - Templates improve your prompt for specific styles + - Available templates: general, photorealistic, illustration, minimalist, sticker, product, comic + - Example showing how template affects the result + - **Note callout:** Template selection coming soon. Currently uses general style. + +4. **Using Reference Images** + - Add referenceImages array with image IDs + - Example with UUID reference + - **Pro Tip callout:** You can also use aliases like `@logo` instead of UUIDs. See [Working with Images](/docs/images) to learn about aliases. + - Auto-detection from prompt text (if you mention @alias in prompt) + +5. **Continuing Generation** + - Pass the same flowId to chain generations + - Each response includes flowId for continuation + - Keep it brief, not a major feature highlight + +6. **Regeneration** + - POST /api/v1/generations/:id/regenerate + - Same params, new image, same URL + +**Link to:** `/docs/api/generations` for full endpoint reference + +--- + +### Page 3: `/docs/images` — Working with Images + +**SEO Title:** "Working with Images | Banatie API Docs" +**Meta Description:** "Upload, manage, and organize your images. CDN delivery, aliases, and image management." + +**Sections:** + +1. **Image URLs** + - All images served via CDN: `https://cdn.banatie.app/...` + - Format: `/{org}/{project}/img/{imageId}` + - Fast, cached, globally distributed + +2. **Uploading Images** + - POST /api/v1/images/upload + - Multipart form data + - Use cases: brand assets, reference images, logos + +3. **Listing & Getting Images** + - GET /api/v1/images + - GET /api/v1/images/:id + +4. **Aliases** + - Assign memorable names to images + - Format: @alias-name (e.g., @logo, @hero-bg) + - PUT /api/v1/images/:id with alias field + - Access via CDN: `/{org}/{project}/img/@hero` + + **Pro Tip callout:** Use aliases for brand assets like `@logo`, `@brand-colors`. Reference them in generations without remembering UUIDs. + +5. **Deleting Images** + - DELETE /api/v1/images/:id + +**Link to:** `/docs/api/images` for full endpoint reference + +--- + +### Page 4: `/docs/live-urls` — Live URL Generation + +**SEO Title:** "Live URLs | Banatie API Docs" +**Meta Description:** "Generate images directly from URL parameters. No API calls needed — just use the URL in your HTML." + +**This is a highlight feature page — make it compelling but not salesy.** + +**Sections:** + +1. **The Concept** + - Generate images by putting prompt in URL + - Use directly in `` + - First request generates, subsequent requests serve from cache + +2. **URL Format** + ``` + https://cdn.banatie.app/{org}/{project}/live/{scope}?prompt=...&aspectRatio=... + ``` + +3. **Try It** + - Show a complete URL example they can open in browser + +4. **Caching Behavior** + - Cache HIT: instant, from CDN edge + - Cache MISS: generates new image (few seconds) + - X-Cache-Status header tells you which + +5. **Scopes** + - Organize live generations by scope + - Set limits per scope + - Auto-created on first use (if enabled) + +6. **Rate Limits** + - 10 new generations per hour per IP + - Cache hits are unlimited + +7. **Use Cases** + - Dynamic placeholders during development + - Personalized content + - Rapid prototyping + - HTML emails with dynamic images + +**Link to:** `/docs/api/live-scopes` for scope management endpoints + +--- + +### Page 5: `/docs/authentication` — Authentication + +**SEO Title:** "Authentication | Banatie API Docs" +**Meta Description:** "How to authenticate with Banatie API using API keys." + +**Sections:** + +1. **Early Access** + - Currently in early access phase + - API keys are issued personally via email + - To request access: sign up on [banatie.app](https://banatie.app) + +2. **Using Your API Key** + - All API requests require `X-API-Key` header + - Example: `curl -H "X-API-Key: your_key_here" ...` + - Keep your key secret, don't commit to git + +3. **Key Types** (brief) + - Project Key: for your application + - Master Key: for admin operations (you probably don't need this) + +**Note callout:** API key management dashboard coming soon. For now, contact us if you need to rotate your key. + +**Link to:** `/docs/generation` as next step + +--- + +### Page 6: `/docs/api` — API Reference Overview + +**SEO Title:** "API Reference | Banatie API Docs" +**Meta Description:** "Complete REST API reference for Banatie. All endpoints, parameters, and response formats." + +**This is a hub page — brief intro then links to subsections.** + +**Sections:** + +1. **Base URL** + ``` + https://api.banatie.app + ``` + +2. **Authentication** + - All endpoints require `X-API-Key` header + - Link to `/docs/authentication` + +3. **Response Format** + - Success: `{ "success": true, "data": {...} }` + - Error: `{ "success": false, "error": {...} }` + - Pagination pattern + +4. **Common Error Codes** + - Table of HTTP status codes and meanings + +5. **Rate Limits** + - 100 requests per hour + - Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset + +6. **Endpoints** + - Card links to each subsection: + - Generations — create and manage image generations + - Images — upload and organize images + - Flows — manage generation chains + - Live Scopes — control live URL generation + +--- + +### Page 7: `/docs/api/generations` — Generations Endpoints + +**SEO Title:** "Generations API | Banatie API Reference" + +**Style:** Dry, complete, scannable. This is reference material. + +**Endpoints to document:** + +``` +POST /api/v1/generations Create generation +GET /api/v1/generations List generations +GET /api/v1/generations/:id Get generation +DELETE /api/v1/generations/:id Delete generation +POST /api/v1/generations/:id/regenerate Regenerate +PUT /api/v1/generations/:id Update generation +``` + +**For each endpoint:** +- Method + Path +- Description (1 line) +- Request parameters (table) +- Request body example (where applicable) +- Response example +- Notes if applicable + +**Source:** Use `/docs/api/image-generation.md` and `/docs/api/image-generation-advanced.md` + +**Important:** The API is synchronous. POST returns completed generation with outputImage immediately. Do NOT show polling flow. + +**Link to:** `/docs/generation` for guide/context + +--- + +### Page 8: `/docs/api/images` — Images Endpoints + +**SEO Title:** "Images API | Banatie API Reference" + +**Endpoints:** + +``` +POST /api/v1/images/upload Upload image +GET /api/v1/images List images +GET /api/v1/images/:id Get image (supports @alias) +PUT /api/v1/images/:id Update image (set alias, metadata) +DELETE /api/v1/images/:id Delete image +``` + +**CDN Endpoints (public, no auth):** + +``` +GET /cdn/{org}/{project}/img/{id} Get image by UUID +GET /cdn/{org}/{project}/img/@{alias} Get image by alias +``` + +**Source:** Use `/docs/api/images-upload.md` + +**Link to:** `/docs/images` for guide/context + +--- + +### Page 9: `/docs/api/flows` — Flows Endpoints + +**SEO Title:** "Flows API | Banatie API Reference" + +**Brief intro:** Flows group related generations together. They're created automatically when you chain generations using the same flowId. + +**Endpoints:** + +``` +GET /api/v1/flows List flows +GET /api/v1/flows/:id Get flow +GET /api/v1/flows/:id/generations List flow generations +GET /api/v1/flows/:id/images List flow images +PUT /api/v1/flows/:id/aliases Update flow aliases +DELETE /api/v1/flows/:id/aliases/:alias Remove flow alias +DELETE /api/v1/flows/:id Delete flow +POST /api/v1/flows/:id/regenerate Regenerate last in flow +``` + +**Source:** Use `/docs/api/image-generation-advanced.md` section on flows + +**Link to:** `/docs/generation` (section on continuing generations) + +--- + +### Page 10: `/docs/api/live-scopes` — Live Scopes Endpoints + +**SEO Title:** "Live Scopes API | Banatie API Reference" + +**Endpoints:** + +``` +POST /api/v1/live/scopes Create scope +GET /api/v1/live/scopes List scopes +GET /api/v1/live/scopes/:slug Get scope +PUT /api/v1/live/scopes/:slug Update scope +DELETE /api/v1/live/scopes/:slug Delete scope +POST /api/v1/live/scopes/:slug/regenerate Regenerate scope images +``` + +**CDN Live Endpoint (public):** + +``` +GET /cdn/{org}/{project}/live/{scope}?prompt=... Live generation +``` + +Query parameters: prompt (required), aspectRatio, autoEnhance, template + +**Source:** Use `/docs/api/live-url.md` + +**Link to:** `/docs/live-urls` for guide/context + +--- + +## Implementation Notes for Claude Code + +1. **Use existing components** — Check `/apps/landing/src/app/docs/` for current implementation patterns + +2. **Correct URLs everywhere:** + - API: `https://api.banatie.app` + - CDN: `https://cdn.banatie.app` + - NOT `.com` — always `.app` + +3. **Example paths use:** `my-org/my-project` (not `default/my-project`) + +4. **No SDK references** — We don't have SDK yet. Don't mention it. + +5. **API is synchronous** — POST /generations returns completed result immediately. No polling. + +6. **Prompt templates, not "enhancement"** — We have templates that improve prompts. Don't call it "auto-enhance" as a standalone feature. + +7. **Breadcrumbs:** Every page should show path (e.g., "Docs > API Reference > Generations") + +8. **Meta tags:** Each page needs proper SEO title and description as specified + +9. **Mobile responsive** — Documentation must work well on mobile + +10. **Code examples:** Use `bash` (curl) as primary. Show request AND response for every endpoint. + +11. **Image dimensions in examples:** Use 1792 x 1008 (16:9) not 1024 x 1024 + +--- + +## File Structure Expected + +``` +apps/landing/src/app/docs/ +├── page.tsx # /docs (Get Started) +├── generation/ +│ └── page.tsx # /docs/generation +├── images/ +│ └── page.tsx # /docs/images +├── live-urls/ +│ └── page.tsx # /docs/live-urls +├── authentication/ +│ └── page.tsx # /docs/authentication +└── api/ + ├── page.tsx # /docs/api (Overview) + ├── generations/ + │ └── page.tsx # /docs/api/generations + ├── images/ + │ └── page.tsx # /docs/api/images + ├── flows/ + │ └── page.tsx # /docs/api/flows + └── live-scopes/ + └── page.tsx # /docs/api/live-scopes +``` + +--- + +## Priority Order for Implementation + +1. `/docs` — Get Started (content provided above) +2. `/docs/generation` — Core feature +3. `/docs/api` — Reference hub +4. `/docs/api/generations` — Most used endpoints +5. `/docs/images` — Working with results +6. `/docs/api/images` — Image endpoints +7. `/docs/live-urls` — Highlight feature +8. `/docs/api/live-scopes` — Live management +9. `/docs/authentication` — Auth info +10. `/docs/api/flows` — Least priority (advanced users) + +--- + +## Quality Checklist + +Before marking complete, verify: + +- [ ] All URLs use `banatie.app` (not `.com`) +- [ ] Example paths use `my-org/my-project` +- [ ] Image dimensions are 1792 x 1008 in examples +- [ ] All code examples are copy-paste ready +- [ ] Every endpoint shows request AND response +- [ ] Tables render correctly +- [ ] Callout blocks used for visual variety +- [ ] Cross-links between guide and reference pages +- [ ] Sidebar navigation matches URL structure +- [ ] Breadcrumbs work on all pages +- [ ] Mobile rendering is acceptable +- [ ] No references to SDK or features that don't exist +- [ ] No polling/async flow — API is synchronous +- [ ] SEO titles and descriptions set for all pages +- [ ] Tone matches "Documentation Spirit" section + +--- + +**End of Specification** From 13f0a4f04fc67f23d9e0d38f9ed368c8205aa1f0 Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Wed, 31 Dec 2025 15:00:44 +0700 Subject: [PATCH 2/8] feat: init docs section --- apps/landing/src/app/docs/api/flows/page.tsx | 334 ++++++++++++++ .../src/app/docs/api/generations/page.tsx | 326 ++++++++++++++ apps/landing/src/app/docs/api/images/page.tsx | 361 +++++++++++++++ .../src/app/docs/api/live-scopes/page.tsx | 419 ++++++++++++++++++ apps/landing/src/app/docs/api/page.tsx | 239 ++++++++++ .../src/app/docs/api/text-to-image/page.tsx | 226 ---------- .../src/app/docs/authentication/page.tsx | 124 ++++++ apps/landing/src/app/docs/generation/page.tsx | 263 +++++++++++ .../app/docs/guides/authentication/page.tsx | 313 ------------- apps/landing/src/app/docs/images/page.tsx | 214 +++++++++ apps/landing/src/app/docs/live-urls/page.tsx | 258 +++++++++++ apps/landing/src/app/docs/page.tsx | 297 +++++++------ .../components/docs/layout/DocsSidebar.tsx | 46 +- 13 files changed, 2708 insertions(+), 712 deletions(-) create mode 100644 apps/landing/src/app/docs/api/flows/page.tsx create mode 100644 apps/landing/src/app/docs/api/generations/page.tsx create mode 100644 apps/landing/src/app/docs/api/images/page.tsx create mode 100644 apps/landing/src/app/docs/api/live-scopes/page.tsx create mode 100644 apps/landing/src/app/docs/api/page.tsx delete mode 100644 apps/landing/src/app/docs/api/text-to-image/page.tsx create mode 100644 apps/landing/src/app/docs/authentication/page.tsx create mode 100644 apps/landing/src/app/docs/generation/page.tsx delete mode 100644 apps/landing/src/app/docs/guides/authentication/page.tsx create mode 100644 apps/landing/src/app/docs/images/page.tsx create mode 100644 apps/landing/src/app/docs/live-urls/page.tsx diff --git a/apps/landing/src/app/docs/api/flows/page.tsx b/apps/landing/src/app/docs/api/flows/page.tsx new file mode 100644 index 0000000..92b356e --- /dev/null +++ b/apps/landing/src/app/docs/api/flows/page.tsx @@ -0,0 +1,334 @@ +'use client'; + +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, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'list-flows', text: 'List Flows', level: 2 }, + { id: 'get-flow', text: 'Get Flow', level: 2 }, + { id: 'list-flow-generations', text: 'List Flow Generations', level: 2 }, + { id: 'list-flow-images', text: 'List Flow Images', level: 2 }, + { id: 'update-flow-aliases', text: 'Update Flow Aliases', level: 2 }, + { id: 'remove-flow-alias', text: 'Remove Flow Alias', level: 2 }, + { id: 'regenerate-flow', text: 'Regenerate Flow', level: 2 }, + { id: 'delete-flow', text: 'Delete Flow', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function FlowsAPIPage() { + return ( + + + +
+ + Overview + +

+ Flows group related generations together. They're created automatically when you chain generations using the same flowId. +

+

+ Flows also support flow-scoped aliases — named references to images that are unique within a flow but don't conflict with project-level aliases. +

+
+ +
+ + List Flows + +

+ Retrieve all flows for your project with computed counts. +

+ + + +
+

Query Parameters

+ limit, 'number', 'Results per page (default: 20, max: 100)'], + [offset, 'number', 'Number of results to skip'], + ]} + /> + + +
+

Example Request

+ +
+ +
+

Response

+ +
+ + +
+ + Get Flow + +

+ Retrieve a single flow with detailed statistics. +

+ + + +
+

Example Request

+ +
+
+ +
+ + List Flow Generations + +

+ Retrieve all generations in a specific flow. +

+ + + +
+

Example Request

+ +
+
+ +
+ + List Flow Images + +

+ Retrieve all images (generated and uploaded) in a flow. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Update Flow Aliases + +

+ Add or update flow-scoped aliases. Aliases are merged with existing ones. +

+ + + +
+

Request Body

+
aliases, 'object', 'Key-value pairs of aliases to add/update'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Remove Flow Alias + +

+ Remove a specific alias from a flow. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Regenerate Flow + +

+ Regenerate the most recent generation in the flow. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Delete Flow + +

+ Delete a flow with cascade deletion. Images with project aliases are preserved. +

+ + + +
+

Example Request

+ +
+ +
+ + Deleting a flow removes all generations and images in it. Images with project aliases are preserved (unlinked from the flow). + +
+
+ + ); +} diff --git a/apps/landing/src/app/docs/api/generations/page.tsx b/apps/landing/src/app/docs/api/generations/page.tsx new file mode 100644 index 0000000..331ad0b --- /dev/null +++ b/apps/landing/src/app/docs/api/generations/page.tsx @@ -0,0 +1,326 @@ +'use client'; + +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, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'create-generation', text: 'Create Generation', level: 2 }, + { id: 'list-generations', text: 'List Generations', level: 2 }, + { id: 'get-generation', text: 'Get Generation', level: 2 }, + { id: 'update-generation', text: 'Update Generation', level: 2 }, + { id: 'regenerate', text: 'Regenerate', level: 2 }, + { id: 'delete-generation', text: 'Delete Generation', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function GenerationsAPIPage() { + return ( + + + +
+ + Create Generation + +

+ Generate a new image from a text prompt. +

+ + + +
+

Request Body

+
prompt, + string, + Yes, + 'Text description of the image to generate', + ], + [ + aspectRatio, + string, + No, + '1:1, 16:9, 9:16, 3:2, 21:9 (default: 1:1)', + ], + [ + referenceImages, + string[], + No, + 'Array of image IDs or @aliases to use as references', + ], + [ + flowId, + string, + No, + 'Associate with existing flow', + ], + [ + alias, + string, + No, + 'Project-scoped alias (@custom-name)', + ], + [ + autoEnhance, + boolean, + No, + 'Enable prompt enhancement (default: true)', + ], + [ + meta, + object, + No, + 'Custom metadata', + ], + ]} + /> + + +
+

Example Request

+ +
+ +
+

Response

+ +
+ + +
+ + List Generations + +

+ Retrieve all generations for your project with optional filtering. +

+ + + +
+

Query Parameters

+
flowId, 'string', 'Filter by flow ID'], + [status, 'string', 'Filter by status: pending, processing, success, failed'], + [limit, 'number', 'Results per page (default: 20, max: 100)'], + [offset, 'number', 'Number of results to skip'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Get Generation + +

+ Retrieve a single generation by ID. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Update Generation + +

+ Update generation parameters. Changing prompt or aspectRatio triggers automatic regeneration. +

+ + + +
+

Request Body

+
prompt, 'string', 'New prompt (triggers regeneration)'], + [aspectRatio, 'string', 'New aspect ratio (triggers regeneration)'], + [flowId, 'string | null', 'Change flow association'], + [meta, 'object', 'Update custom metadata'], + ]} + /> + + +
+ + Changing prompt or aspectRatio triggers a new generation. The image ID and URL remain the same — only the content changes. + +
+ + +
+ + Regenerate + +

+ Create a new image using the exact same parameters. Useful for getting a different result or recovering from failures. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Delete Generation + +

+ Delete a generation and its output image. Images with project aliases are preserved. +

+ + + +
+

Example Request

+ +
+ +
+

Response

+ +
+
+ + ); +} 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..ae98cde --- /dev/null +++ b/apps/landing/src/app/docs/api/images/page.tsx @@ -0,0 +1,361 @@ +'use client'; + +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, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'upload-image', text: 'Upload Image', level: 2 }, + { id: 'list-images', text: 'List Images', level: 2 }, + { id: 'get-image', text: 'Get Image', level: 2 }, + { id: 'update-image', text: 'Update Image', level: 2 }, + { id: 'assign-alias', text: 'Assign Alias', level: 2 }, + { id: 'delete-image', text: 'Delete Image', level: 2 }, + { id: 'cdn-endpoints', text: 'CDN Endpoints', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function ImagesAPIPage() { + return ( + + + +
+ + Upload Image + +

+ Upload an image file to your project storage. +

+ + + +
+

Form Data

+
file, + file, + Yes, + 'Image file (max 5MB, JPEG/PNG/WebP)', + ], + [ + alias, + string, + No, + 'Project-scoped alias (@custom-name)', + ], + [ + flowId, + string, + No, + 'Associate with flow', + ], + [ + meta, + string, + No, + 'Custom metadata (JSON string)', + ], + ]} + /> + + +
+

Example Request

+ +
+ +
+

Response

+ +
+ + +
+ + List Images + +

+ Retrieve all images in your project with optional filtering. +

+ + + +
+

Query Parameters

+
flowId, 'string', 'Filter by flow ID'], + [source, 'string', 'Filter by source: generated, uploaded'], + [alias, 'string', 'Filter by exact alias match'], + [limit, 'number', 'Results per page (default: 20, max: 100)'], + [offset, 'number', 'Number of results to skip'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Get Image + +

+ Retrieve a single image by ID or alias. +

+ + + +
+

Example Requests

+ +
+
+ +
+ + Update Image + +

+ Update image metadata (focal point and custom metadata). +

+ + + +
+

Request Body

+
focalPoint, 'object', 'Focal point for cropping {x: 0-1, y: 0-1}'], + [meta, 'object', 'Custom metadata'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Assign Alias + +

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

+ + + +
+

Request Body

+
alias, 'string | null', 'Alias to assign (@name) or null to remove'], + ]} + /> + + +
+

Example Requests

+ +
+ + +
+ + Delete Image + +

+ Permanently delete an image from storage. +

+ + + +
+

Example Request

+ +
+ +
+ + Deletion is permanent. The image file and all references are removed from storage. + +
+
+ +
+ + CDN Endpoints + +

+ Access images directly via CDN (public, no authentication required): +

+ +
+
+

By Image ID

+ +
+ +
+

By Alias

+ +
+
+ +
+ + CDN URLs are public and don't require authentication. They return image bytes directly with appropriate caching headers. + +
+
+ + ); +} diff --git a/apps/landing/src/app/docs/api/live-scopes/page.tsx b/apps/landing/src/app/docs/api/live-scopes/page.tsx new file mode 100644 index 0000000..3b6e8ef --- /dev/null +++ b/apps/landing/src/app/docs/api/live-scopes/page.tsx @@ -0,0 +1,419 @@ +'use client'; + +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, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'create-scope', text: 'Create Scope', level: 2 }, + { id: 'list-scopes', text: 'List Scopes', level: 2 }, + { id: 'get-scope', text: 'Get Scope', level: 2 }, + { id: 'update-scope', text: 'Update Scope', level: 2 }, + { id: 'regenerate-scope', text: 'Regenerate Scope', level: 2 }, + { id: 'delete-scope', text: 'Delete Scope', level: 2 }, + { id: 'cdn-live-endpoint', text: 'CDN Live Endpoint', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function LiveScopesAPIPage() { + return ( + + + +
+ + Overview + +

+ Live scopes organize live URL generations. Each scope has its own generation limit and can be configured independently. +

+

+ Scopes are auto-created on first use, but you can pre-configure them via this API to set custom limits. +

+
+ +
+ + Create Scope + +

+ Create a new live scope with custom settings. +

+ + + +
+

Request Body

+
slug, + string, + Yes, + 'Unique scope identifier (alphanumeric + hyphens + underscores)', + ], + [ + allowNewGenerations, + boolean, + No, + 'Allow new generations (default: true)', + ], + [ + newGenerationsLimit, + number, + No, + 'Maximum generations allowed (default: 30)', + ], + [ + meta, + object, + No, + 'Custom metadata', + ], + ]} + /> + + +
+

Example Request

+ +
+ +
+

Response

+ +
+ + +
+ + List Scopes + +

+ Retrieve all live scopes for your project. +

+ + + +
+

Query Parameters

+
slug, 'string', 'Filter by exact slug match'], + [limit, 'number', 'Results per page (default: 20, max: 100)'], + [offset, 'number', 'Number of results to skip'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Get Scope + +

+ Retrieve a single scope with statistics. +

+ + + +
+

Example Request

+ +
+
+ +
+ + Update Scope + +

+ Update scope settings. Changes take effect immediately. +

+ + + +
+

Request Body

+
allowNewGenerations, 'boolean', 'Allow/disallow new generations'], + [newGenerationsLimit, 'number', 'Update generation limit'], + [meta, 'object', 'Update custom metadata'], + ]} + /> + + +
+

Example Request

+ +
+ + +
+ + Regenerate Scope + +

+ Regenerate images in a scope. Can regenerate a specific image or all images. +

+ + + +
+

Request Body

+
imageId, 'string', 'Specific image to regenerate (omit for all)'], + ]} + /> + + +
+

Example Requests

+ +
+ +
+

Response

+ +
+ + +
+ + Delete Scope + +

+ Delete a scope and all its cached images. +

+ + + +
+

Example Request

+ +
+ +
+ + Deleting a scope permanently removes all cached images in it. This cannot be undone. + +
+
+ +
+ + CDN Live Endpoint + +

+ Public endpoint for live URL generation (no authentication required): +

+ + + +
+

Query Parameters

+
prompt, + Yes, + 'Text description of the image to generate', + ], + [ + aspectRatio, + No, + 'Image ratio (default: 1:1)', + ], + [ + autoEnhance, + No, + 'Enable prompt enhancement', + ], + [ + template, + No, + 'Enhancement template to use', + ], + ]} + /> + + +
+

Example

+ +
+ +
+

Response Headers

+
X-Cache-Status, 'HIT (cached) or MISS (generated)'], + [X-Scope, 'Scope identifier'], + [X-Image-Id, 'Image UUID'], + [X-RateLimit-Remaining, 'Remaining IP rate limit (on MISS)'], + ]} + /> + + + + ); +} diff --git a/apps/landing/src/app/docs/api/page.tsx b/apps/landing/src/app/docs/api/page.tsx new file mode 100644 index 0000000..13c1adc --- /dev/null +++ b/apps/landing/src/app/docs/api/page.tsx @@ -0,0 +1,239 @@ +'use client'; + +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, + LinkCard, + LinkCardGrid, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'base-url', text: 'Base URL', level: 2 }, + { id: 'authentication', text: 'Authentication', level: 2 }, + { id: 'response-format', text: 'Response Format', level: 2 }, + { id: 'error-codes', text: 'Common Error Codes', level: 2 }, + { id: 'rate-limits', text: 'Rate Limits', level: 2 }, + { id: 'endpoints', text: 'Endpoints', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function APIOverviewPage() { + return ( + + + +
+ + Base URL + + + +
+ +
+ + Authentication + +

+ All endpoints require the X-API-Key header: +

+ + + +

+ See Authentication for details on obtaining and using API keys. +

+
+ +
+ + Response Format + +

+ All responses follow a consistent JSON structure: +

+ +
+
+

Success Response:

+ +
+ +
+

Error Response:

+ +
+ +
+

Paginated Response:

+ +
+
+
+ +
+ + Common Error Codes + + +
400, + 'VALIDATION_ERROR', + 'Missing or invalid parameters', + ], + [ + 401, + 'UNAUTHORIZED', + 'Missing or invalid API key', + ], + [ + 404, + '*_NOT_FOUND', + 'Requested resource not found', + ], + [ + 409, + 'ALIAS_CONFLICT', + 'Alias already exists', + ], + [ + 429, + 'RATE_LIMIT_EXCEEDED', + 'Too many requests', + ], + [ + 500, + 'INTERNAL_ERROR', + 'Server error', + ], + ]} + /> + + +
+ + Rate Limits + +

+ API requests are rate limited to 100 requests per hour per API key. +

+

+ Rate limit headers are included in every response: +

+ +
X-RateLimit-Limit, 'Maximum requests per hour'], + [X-RateLimit-Remaining, 'Requests remaining in current window'], + [X-RateLimit-Reset, 'Unix timestamp when limit resets'], + ]} + /> + + +
+ + Endpoints + + + + + + + + +
+ + ); +} 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/authentication/page.tsx b/apps/landing/src/app/docs/authentication/page.tsx new file mode 100644 index 0000000..190e315 --- /dev/null +++ b/apps/landing/src/app/docs/authentication/page.tsx @@ -0,0 +1,124 @@ +'use client'; + +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: 'early-access', text: 'Early Access', level: 2 }, + { id: 'using-your-api-key', text: 'Using Your API Key', level: 2 }, + { id: 'key-types', text: 'Key Types', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function AuthenticationPage() { + return ( + + + +
+ + Early Access + +

+ We're currently in early access phase. API keys are issued personally via email. +

+

+ To request access: Sign up at banatie.app. We'll send your API key within 24 hours. +

+
+ +
+ + Using Your API Key + +

+ All API requests require the X-API-Key header: +

+ + + +
+ + Keep your API key secure. Don't commit it to version control or expose it in client-side code. Use environment variables in your applications. + +
+
+ +
+ + Key Types + +

+ Banatie uses two types of API keys: +

+ +
Project Key, + 'Image generation, uploads, images', + 90 days, + 'Your application integration', + ], + [ + Master Key, + 'Full admin access, key management', + Never expires, + 'Server-side admin operations', + ], + ]} + /> + +

+ You'll receive a Project Key for your application. Master Keys are for administrative operations — you probably don't need one. +

+ +
+ + API key management dashboard coming soon. For now, contact us if you need to rotate your key. + +
+ + + ); +} diff --git a/apps/landing/src/app/docs/generation/page.tsx b/apps/landing/src/app/docs/generation/page.tsx new file mode 100644 index 0000000..db9fb61 --- /dev/null +++ b/apps/landing/src/app/docs/generation/page.tsx @@ -0,0 +1,263 @@ +'use client'; + +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, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'basic-generation', text: 'Basic Generation', level: 2 }, + { id: 'aspect-ratios', text: 'Aspect Ratios', level: 2 }, + { id: 'prompt-templates', text: 'Prompt Templates', level: 2 }, + { id: 'reference-images', text: 'Using Reference Images', level: 2 }, + { id: 'continuing-generation', text: 'Continuing Generation', level: 2 }, + { id: 'regeneration', text: 'Regeneration', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function GenerationPage() { + return ( + + + +
+ + Basic Generation + +

+ Generate an image by sending a text prompt to the generations endpoint: +

+ + + +

+ The response contains your generated image immediately: +

+ + + +

+ One request, one result. The storageUrl is your production-ready image, served via CDN. +

+
+ +
+ + Aspect Ratios + +

+ Choose the aspect ratio that fits your use case: +

+ +
1:1, + '1024 x 1024', + 'Social media posts, profile pictures, thumbnails', + ], + [ + 16:9, + '1792 x 1008', + 'Blog headers, presentations, video thumbnails', + ], + [ + 9:16, + '1008 x 1792', + 'Stories, mobile backgrounds, vertical banners', + ], + [ + 3:2, + '1536 x 1024', + 'Photography-style images, print layouts', + ], + [ + 21:9, + '2016 x 864', + 'Ultra-wide banners, cinematic headers', + ], + ]} + /> + +

+ Default is 1:1 if not specified. +

+ + +
+ + Prompt Templates + +

+ Templates improve your prompt for specific styles. Available templates: +

+ +
general, 'Balanced style for most use cases'], + [photorealistic, 'Photo-like realism with natural lighting'], + [illustration, 'Artistic illustration style'], + [minimalist, 'Clean, simple compositions'], + [sticker, 'Sticker-style with clear edges'], + [product, 'E-commerce product photography'], + [comic, 'Comic book visual style'], + ]} + /> + +
+ + Template selection coming soon. Currently uses general style for all generations. + +
+ + +
+ + Using Reference Images + +

+ Add reference images for style guidance or context. Pass image IDs or aliases in the referenceImages array: +

+ + + +
+ + Pro Tip: Use aliases like @logo instead of UUIDs. See Working with Images to learn about aliases. + +
+ +

+ You can also mention aliases directly in your prompt text — they're auto-detected: +

+ + +
+ +
+ + Continuing Generation + +

+ Chain multiple generations together by passing the same flowId: +

+ + + +

+ Each response includes a flowId you can use to continue the sequence. Flows help organize related generations together. +

+
+ +
+ + Regeneration + +

+ Want a different result with the same parameters? Regenerate an existing generation: +

+ + + +

+ Same prompt, new image. The generation ID and URL stay the same — the image content is replaced. +

+
+ + ); +} 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/images/page.tsx b/apps/landing/src/app/docs/images/page.tsx new file mode 100644 index 0000000..41d4cea --- /dev/null +++ b/apps/landing/src/app/docs/images/page.tsx @@ -0,0 +1,214 @@ +'use client'; + +import { TipBox } from '@/components/docs/shared/TipBox'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; +import { DocPage } from '@/components/docs/layout/DocPage'; +import { + Hero, + SectionHeader, + InlineCode, + ResponseBlock, +} from '@/components/docs/blocks'; + +const tocItems = [ + { id: 'image-urls', text: 'Image URLs', level: 2 }, + { id: 'uploading-images', text: 'Uploading Images', level: 2 }, + { id: 'listing-images', text: 'Listing & Getting Images', level: 2 }, + { id: 'aliases', text: 'Aliases', level: 2 }, + { id: 'deleting-images', text: 'Deleting Images', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function ImagesPage() { + return ( + + + +
+ + Image URLs + +

+ All images are served via CDN with this URL structure: +

+ + + +

+ URLs are permanent, fast, and cached globally. Use them directly in your applications. +

+
+ +
+ + Uploading Images + +

+ Upload your own images for use as brand assets, references, or logos: +

+ + + +

+ Response includes the CDN URL and image details: +

+ + +
+ +
+ + Listing & Getting Images + +

+ List all images in your project: +

+ + + +

+ Get a specific image by ID or alias: +

+ + +
+ +
+ + Aliases + +

+ Assign memorable names to images. Aliases start with @ and make it easy to reference images without remembering UUIDs. +

+ + + +

+ Access images via CDN using their alias: +

+ + + +
+ + Pro Tip: Use aliases for brand assets like @logo, @brand-colors. Reference them in generations without remembering UUIDs. + +
+ +

+ Remove an alias by setting it to null: +

+ + +
+ +
+ + Deleting Images + +

+ Delete an image by ID or alias. This permanently removes the image from storage. +

+ + + +
+ + Deletion is permanent. The image file and all references are removed. + +
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/live-urls/page.tsx b/apps/landing/src/app/docs/live-urls/page.tsx new file mode 100644 index 0000000..39e2cc9 --- /dev/null +++ b/apps/landing/src/app/docs/live-urls/page.tsx @@ -0,0 +1,258 @@ +'use client'; + +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: 'the-concept', text: 'The Concept', level: 2 }, + { id: 'url-format', text: 'URL Format', level: 2 }, + { id: 'try-it', text: 'Try It', level: 2 }, + { id: 'caching-behavior', text: 'Caching Behavior', level: 2 }, + { id: 'scopes', text: 'Scopes', level: 2 }, + { id: 'rate-limits', text: 'Rate Limits', level: 2 }, + { id: 'use-cases', text: 'Use Cases', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function LiveUrlsPage() { + return ( + + + +
+ + The Concept + +

+ Put your prompt in a URL. Use it directly in an <img src="..."> tag. +

+

+ First request generates the image. All subsequent requests serve it from cache instantly. +

+
+ +
+ + URL Format + + + + +

+ Query parameters: +

+ +
prompt, + Yes, + 'Text description of the image to generate', + ], + [ + aspectRatio, + No, + 'Image ratio: 1:1, 16:9, 9:16, 3:2 (default: 1:1)', + ], + [ + autoEnhance, + No, + 'Enable prompt enhancement (default: false)', + ], + [ + template, + No, + 'Enhancement template to use', + ], + ]} + /> + + +
+ + Try It + +

+ Open this URL in your browser: +

+ + + +

+ Or use it directly in HTML: +

+ + `} + language="html" + filename="HTML Usage" + /> +
+ +
+ + Caching Behavior + +

+ The response includes an X-Cache-Status header: +

+ +
HIT, + 'Image served from cache', + 'Instant (milliseconds)', + ], + [ + MISS, + 'New image generated', + 'A few seconds', + ], + ]} + /> + +

+ Cache hits are unlimited and don't count toward rate limits. Only new generations (cache MISS) are rate limited. +

+ + +
+ + Scopes + +

+ Scopes organize your live generations. Each scope has its own generation limit. +

+ + + +

+ Scopes are auto-created on first use. You can also pre-configure them via the API to set custom limits. +

+
+ +
+ + Rate Limits + + +
10 new generations/hour, + 'Only applies to cache MISS', + ], + [ + 'Per Scope', + 30 generations, + 'Configurable via API', + ], + [ + 'Cache Hits', + Unlimited, + 'No limits on cached images', + ], + ]} + /> + +
+ + Rate limits protect the service from abuse. For high-volume needs, use the generations API directly. + +
+ + +
+ + Use Cases + + +
    +
  • + +
    + Dynamic placeholders +

    Generate placeholder images during development that match your design intent.

    +
    +
  • +
  • + +
    + Personalized content +

    Create unique images based on user data or preferences.

    +
    +
  • +
  • + +
    + Rapid prototyping +

    Test different visuals without writing backend code.

    +
    +
  • +
  • + +
    + HTML emails +

    Include dynamic images in email templates with just a URL.

    +
    +
  • +
+
+ + ); +} diff --git a/apps/landing/src/app/docs/page.tsx b/apps/landing/src/app/docs/page.tsx index a1c3e0b..fd5524d 100644 --- a/apps/landing/src/app/docs/page.tsx +++ b/apps/landing/src/app/docs/page.tsx @@ -1,14 +1,5 @@ 'use client'; -/** - * Getting Started Page - Production Documentation - * - * 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 { CodeBlock } from '@/components/docs/shared/CodeBlock'; import { DocPage } from '@/components/docs/layout/DocPage'; @@ -16,14 +7,16 @@ import { Hero, SectionHeader, ResponseBlock, + LinkCard, + LinkCardGrid, } from '@/components/docs/blocks'; const tocItems = [ - { id: 'introduction', text: 'Introduction', level: 2 }, - { id: 'quick-start', text: 'Quick Start', level: 2 }, - { id: 'installation', text: 'Installation', level: 3 }, - { id: 'authentication', text: 'Authentication', level: 3 }, - { id: 'first-request', text: 'Your First Request', level: 2 }, + { id: 'what-is-banatie', text: 'What is Banatie?', level: 2 }, + { id: 'your-first-image', text: 'Your First Image', level: 2 }, + { id: 'production-ready', text: 'Production Ready', level: 2 }, + { id: 'live-urls', text: 'Live URLs', level: 2 }, + { id: 'get-your-api-key', text: 'Get Your API Key', level: 2 }, { id: 'next-steps', text: 'Next Steps', level: 2 }, ]; @@ -36,161 +29,167 @@ export default function GettingStartedPage() { ]} tocItems={tocItems} nextSteps={{ - description: - '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', - description: 'Explore all available endpoints, parameters, and response formats.', + href: '/docs/generation', + title: 'Image Generation', + description: 'Aspect ratios, prompt templates, using references.', accent: 'primary', }, { - href: '/docs/guides/authentication', - title: 'Authentication Guide', - description: 'Learn about API keys, rate limits, and security best practices.', + href: '/docs/images', + title: 'Working with Images', + description: 'Upload your own, organize with aliases.', + accent: 'secondary', + }, + { + href: '/docs/live-urls', + title: 'Live URLs', + description: 'Generate images directly from URL parameters.', + accent: 'primary', + }, + { + href: '/docs/api', + title: 'API Reference', + description: 'Full endpoint documentation.', accent: 'secondary', }, ], }} > + - {/* Hero Section */} - + + What is Banatie? + +

+ Banatie is an image generation API for developers. Send a text prompt, get a production-ready image delivered via CDN. +

+

+ Simple REST API. Optimized AI models that deliver consistent results. Images ready for production use immediately. +

+ + +
+ + Your First Image + +

+ Once you have your API key, generate an image with a single request: +

+ + - {/* Introduction */} -
- - 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. -

-

- Whether you are building a content creation platform, e-commerce site, or creative tool, - Banatie provides the infrastructure you need to generate high-quality images at scale. -

+

+ That's it. The response contains your image: +

- {/* Compact Tip Box */} - - New to API integration? Start with our{' '} - - code examples - {' '} - to see common use cases in action. - -
- - {/* Quick Start */} -
- - Quick Start - - -
- - Installation - -

- Banatie is a REST API, so you do not need to install any libraries. However, we provide - SDKs for popular languages to make integration easier. -

- - -
- -
- - Authentication - -

- All API requests require an API key. You can create an API key from your dashboard or - using the bootstrap endpoint for initial setup. -

- - {/* Prominent Tip Box for Security Warning */} -
- - Security Best Practice: Keep your API keys secure. - Never commit them to public repositories or expose them in client-side code. Use environment - variables and server-side implementations for production applications. - -
- - -
-
- - {/* First Request */} -
- - Your First Request - -

- Let's generate your first image! This example uses curl, but you can use any HTTP client - or our SDKs. -

- - - -
-

Expected Response:

- -
-
+ /> +

+ Open storageUrl in your browser — there's your robot. +

+
+ +
+ + Production Ready + +

+ The image URL is permanent and served via global CDN. What this means for you: +

+ +
    +
  • + + Fast access — images load in milliseconds +
  • +
  • + + Edge cached — served from locations closest to your users +
  • +
  • + + Global distribution — works fast everywhere in the world +
  • +
+ +

+ One request. Production-ready result. Drop the URL into your app and ship. +

+
+ +
+ + Live URLs + +

+ Want to skip the API call entirely? Generate images directly from a URL: +

+ + + +

+ Put this in an <img src="..."> tag. First request generates the image, all subsequent requests serve it from cache instantly. +

+ + + Perfect for placeholders, dynamic content, and rapid prototyping. + + +

+ Learn more about Live URLs → +

+
+ +
+ + Get Your API Key + +

+ We're currently in early access. API keys are issued personally. +

+ +
+

To request access:

+
    +
  1. Go to banatie.app
  2. +
  3. Enter your email in the signup form
  4. +
  5. We'll send your API key within 24 hours
  6. +
+
+
); } diff --git a/apps/landing/src/components/docs/layout/DocsSidebar.tsx b/apps/landing/src/components/docs/layout/DocsSidebar.tsx index b5e6d6a..f33055d 100644 --- a/apps/landing/src/components/docs/layout/DocsSidebar.tsx +++ b/apps/landing/src/components/docs/layout/DocsSidebar.tsx @@ -41,37 +41,38 @@ const navigationItems: NavItem[] = [ { label: 'Getting Started', href: '/docs', - icon: '🚀', + }, + { + label: 'Image Generation', + href: '/docs/generation', + }, + { + label: 'Working with Images', + href: '/docs/images', + }, + { + label: 'Live URLs', + href: '/docs/live-urls', + }, + { + label: 'Authentication', + href: '/docs/authentication', }, { label: 'API Reference', href: '/docs/api', - icon: '📚', children: [ - { label: 'Text to Image', href: '/docs/api/text-to-image' }, - { label: 'Upload', href: '/docs/api/upload' }, + { label: 'Overview', href: '/docs/api' }, + { label: 'Generations', href: '/docs/api/generations' }, { label: 'Images', href: '/docs/api/images' }, + { label: 'Flows', href: '/docs/api/flows' }, + { label: 'Live Scopes', href: '/docs/api/live-scopes' }, ], }, - { - label: 'Guides', - href: '/docs/guides', - icon: '📖', - children: [ - { label: 'Authentication', href: '/docs/guides/authentication' }, - { label: 'Error Handling', href: '/docs/guides/error-handling' }, - { label: 'Rate Limits', href: '/docs/guides/rate-limits' }, - ], - }, - { - label: 'Examples', - href: '/docs/examples', - icon: '💡', - }, ]; export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => { - const [expandedSections, setExpandedSections] = useState(['API Reference', 'Guides']); + const [expandedSections, setExpandedSections] = useState(['API Reference']); const toggleSection = (label: string) => { setExpandedSections((prev) => @@ -119,10 +120,7 @@ export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => { ${active ? 'bg-purple-500/10 text-white font-medium' : 'text-gray-400 hover:text-white hover:bg-white/5'} `} > - - {item.icon && {item.icon}} - {item.label} - + {item.label} {hasChildren && ( Date: Wed, 31 Dec 2025 16:03:46 +0700 Subject: [PATCH 3/8] fix(docs): sidebar active state not showing due to trailing slash mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next.js usePathname() returns paths with trailing slashes during static generation (e.g., /docs/) but navigation hrefs use paths without trailing slashes (e.g., /docs). The strict equality comparison was always failing. Added path normalization to strip trailing slashes before comparison. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- apps/landing/src/components/docs/layout/DocsSidebar.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/landing/src/components/docs/layout/DocsSidebar.tsx b/apps/landing/src/components/docs/layout/DocsSidebar.tsx index f33055d..aaaf960 100644 --- a/apps/landing/src/components/docs/layout/DocsSidebar.tsx +++ b/apps/landing/src/components/docs/layout/DocsSidebar.tsx @@ -80,7 +80,11 @@ export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => { ); }; - const isActive = (href: string) => currentPath === href; + // Normalize path by removing trailing slash (except for root) + const normalizePath = (path: string) => (path.length > 1 && path.endsWith('/') ? path.slice(0, -1) : path); + const normalizedCurrentPath = normalizePath(currentPath); + + const isActive = (href: string) => normalizedCurrentPath === href; const isExpanded = (label: string) => expandedSections.includes(label); return ( From 21dfd31338e0422e5ec7db5b6f4e56cad723ae59 Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Wed, 31 Dec 2025 18:35:05 +0700 Subject: [PATCH 4/8] feat(landing): implement route groups for different header behaviors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created (landings) route group for home page with sticky header - Created (apps) route group for docs/demo/admin with scrollable header - Moved page components to respective route groups - Updated root layout to be minimal (no header/footer) - Each route group has its own layout with appropriate header style - Updated Footer and layouts to use public folder logo path This enables sticky header on landing pages while docs/demo pages have a header that scrolls away with content. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../app/{ => (apps)}/admin/apikeys/page.tsx | 0 .../src/app/{ => (apps)}/admin/layout.tsx | 0 .../app/{ => (apps)}/admin/master/page.tsx | 0 .../app/{ => (apps)}/demo/gallery/page.tsx | 0 .../src/app/{ => (apps)}/demo/layout.tsx | 0 .../src/app/{ => (apps)}/demo/tti/page.tsx | 0 .../src/app/{ => (apps)}/demo/upload/page.tsx | 0 .../app/{ => (apps)}/docs/api/flows/page.tsx | 0 .../docs/api/generations/page.tsx | 0 .../app/{ => (apps)}/docs/api/images/page.tsx | 0 .../docs/api/live-scopes/page.tsx | 0 .../src/app/{ => (apps)}/docs/api/page.tsx | 0 .../{ => (apps)}/docs/authentication/page.tsx | 0 .../app/{ => (apps)}/docs/generation/page.tsx | 0 .../src/app/{ => (apps)}/docs/images/page.tsx | 0 .../src/app/{ => (apps)}/docs/layout.tsx | 0 .../app/{ => (apps)}/docs/live-urls/page.tsx | 0 .../src/app/{ => (apps)}/docs/page.tsx | 0 apps/landing/src/app/(apps)/layout.tsx | 38 ++++++++++++++++++ .../src/app/{ => (landings)}/_assets/1.jpg | Bin .../src/app/{ => (landings)}/_assets/2.jpg | Bin .../src/app/{ => (landings)}/_assets/3.jpg | Bin .../src/app/{ => (landings)}/_assets/4.jpg | Bin .../src/app/{ => (landings)}/_assets/5.jpg | Bin .../src/app/{ => (landings)}/_assets/6.jpg | Bin .../src/app/{ => (landings)}/_assets/7.jpg | Bin .../src/app/{ => (landings)}/_assets/8.jpg | Bin .../src/app/{ => (landings)}/_assets/9.jpg | Bin .../_assets/banatie-logo-horisontal.png | Bin .../_components/ApiExampleSection.tsx | 0 .../_components/BackgroundBlobs.tsx | 0 .../_components/FinalCtaSection.tsx | 0 .../_components/GeminiSection.tsx | 0 .../_components/GlowEffect.tsx | 0 .../{ => (landings)}/_components/HeroGlow.tsx | 0 .../_components/HeroSection.tsx | 0 .../_components/HowItWorksSection.tsx | 0 .../_components/IntegrationsSection.tsx | 0 .../_components/KeyFeaturesSection.tsx | 0 .../_components/ProblemSolutionSection.tsx | 0 .../_components/PromptUrlsSection.tsx | 0 .../_components/ShapeTheFutureSection.tsx | 0 .../_components/WaitlistEmailForm.tsx | 0 .../_components/WaitlistPopup.tsx | 0 .../app/{ => (landings)}/_components/index.ts | 0 apps/landing/src/app/(landings)/layout.tsx | 38 ++++++++++++++++++ .../landing/src/app/{ => (landings)}/page.tsx | 0 apps/landing/src/app/layout.tsx | 28 ------------- apps/landing/src/components/shared/Footer.tsx | 3 +- 49 files changed, 77 insertions(+), 30 deletions(-) rename apps/landing/src/app/{ => (apps)}/admin/apikeys/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/admin/layout.tsx (100%) rename apps/landing/src/app/{ => (apps)}/admin/master/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/demo/gallery/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/demo/layout.tsx (100%) rename apps/landing/src/app/{ => (apps)}/demo/tti/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/demo/upload/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/api/flows/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/api/generations/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/api/images/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/api/live-scopes/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/api/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/authentication/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/generation/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/images/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/layout.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/live-urls/page.tsx (100%) rename apps/landing/src/app/{ => (apps)}/docs/page.tsx (100%) create mode 100644 apps/landing/src/app/(apps)/layout.tsx rename apps/landing/src/app/{ => (landings)}/_assets/1.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/2.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/3.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/4.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/5.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/6.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/7.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/8.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/9.jpg (100%) rename apps/landing/src/app/{ => (landings)}/_assets/banatie-logo-horisontal.png (100%) rename apps/landing/src/app/{ => (landings)}/_components/ApiExampleSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/BackgroundBlobs.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/FinalCtaSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/GeminiSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/GlowEffect.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/HeroGlow.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/HeroSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/HowItWorksSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/IntegrationsSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/KeyFeaturesSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/ProblemSolutionSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/PromptUrlsSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/ShapeTheFutureSection.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/WaitlistEmailForm.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/WaitlistPopup.tsx (100%) rename apps/landing/src/app/{ => (landings)}/_components/index.ts (100%) create mode 100644 apps/landing/src/app/(landings)/layout.tsx rename apps/landing/src/app/{ => (landings)}/page.tsx (100%) diff --git a/apps/landing/src/app/admin/apikeys/page.tsx b/apps/landing/src/app/(apps)/admin/apikeys/page.tsx similarity index 100% rename from apps/landing/src/app/admin/apikeys/page.tsx rename to apps/landing/src/app/(apps)/admin/apikeys/page.tsx diff --git a/apps/landing/src/app/admin/layout.tsx b/apps/landing/src/app/(apps)/admin/layout.tsx similarity index 100% rename from apps/landing/src/app/admin/layout.tsx rename to apps/landing/src/app/(apps)/admin/layout.tsx diff --git a/apps/landing/src/app/admin/master/page.tsx b/apps/landing/src/app/(apps)/admin/master/page.tsx similarity index 100% rename from apps/landing/src/app/admin/master/page.tsx rename to apps/landing/src/app/(apps)/admin/master/page.tsx diff --git a/apps/landing/src/app/demo/gallery/page.tsx b/apps/landing/src/app/(apps)/demo/gallery/page.tsx similarity index 100% rename from apps/landing/src/app/demo/gallery/page.tsx rename to apps/landing/src/app/(apps)/demo/gallery/page.tsx diff --git a/apps/landing/src/app/demo/layout.tsx b/apps/landing/src/app/(apps)/demo/layout.tsx similarity index 100% rename from apps/landing/src/app/demo/layout.tsx rename to apps/landing/src/app/(apps)/demo/layout.tsx diff --git a/apps/landing/src/app/demo/tti/page.tsx b/apps/landing/src/app/(apps)/demo/tti/page.tsx similarity index 100% rename from apps/landing/src/app/demo/tti/page.tsx rename to apps/landing/src/app/(apps)/demo/tti/page.tsx diff --git a/apps/landing/src/app/demo/upload/page.tsx b/apps/landing/src/app/(apps)/demo/upload/page.tsx similarity index 100% rename from apps/landing/src/app/demo/upload/page.tsx rename to apps/landing/src/app/(apps)/demo/upload/page.tsx diff --git a/apps/landing/src/app/docs/api/flows/page.tsx b/apps/landing/src/app/(apps)/docs/api/flows/page.tsx similarity index 100% rename from apps/landing/src/app/docs/api/flows/page.tsx rename to apps/landing/src/app/(apps)/docs/api/flows/page.tsx diff --git a/apps/landing/src/app/docs/api/generations/page.tsx b/apps/landing/src/app/(apps)/docs/api/generations/page.tsx similarity index 100% rename from apps/landing/src/app/docs/api/generations/page.tsx rename to apps/landing/src/app/(apps)/docs/api/generations/page.tsx diff --git a/apps/landing/src/app/docs/api/images/page.tsx b/apps/landing/src/app/(apps)/docs/api/images/page.tsx similarity index 100% rename from apps/landing/src/app/docs/api/images/page.tsx rename to apps/landing/src/app/(apps)/docs/api/images/page.tsx diff --git a/apps/landing/src/app/docs/api/live-scopes/page.tsx b/apps/landing/src/app/(apps)/docs/api/live-scopes/page.tsx similarity index 100% rename from apps/landing/src/app/docs/api/live-scopes/page.tsx rename to apps/landing/src/app/(apps)/docs/api/live-scopes/page.tsx diff --git a/apps/landing/src/app/docs/api/page.tsx b/apps/landing/src/app/(apps)/docs/api/page.tsx similarity index 100% rename from apps/landing/src/app/docs/api/page.tsx rename to apps/landing/src/app/(apps)/docs/api/page.tsx diff --git a/apps/landing/src/app/docs/authentication/page.tsx b/apps/landing/src/app/(apps)/docs/authentication/page.tsx similarity index 100% rename from apps/landing/src/app/docs/authentication/page.tsx rename to apps/landing/src/app/(apps)/docs/authentication/page.tsx diff --git a/apps/landing/src/app/docs/generation/page.tsx b/apps/landing/src/app/(apps)/docs/generation/page.tsx similarity index 100% rename from apps/landing/src/app/docs/generation/page.tsx rename to apps/landing/src/app/(apps)/docs/generation/page.tsx diff --git a/apps/landing/src/app/docs/images/page.tsx b/apps/landing/src/app/(apps)/docs/images/page.tsx similarity index 100% rename from apps/landing/src/app/docs/images/page.tsx rename to apps/landing/src/app/(apps)/docs/images/page.tsx diff --git a/apps/landing/src/app/docs/layout.tsx b/apps/landing/src/app/(apps)/docs/layout.tsx similarity index 100% rename from apps/landing/src/app/docs/layout.tsx rename to apps/landing/src/app/(apps)/docs/layout.tsx diff --git a/apps/landing/src/app/docs/live-urls/page.tsx b/apps/landing/src/app/(apps)/docs/live-urls/page.tsx similarity index 100% rename from apps/landing/src/app/docs/live-urls/page.tsx rename to apps/landing/src/app/(apps)/docs/live-urls/page.tsx diff --git a/apps/landing/src/app/docs/page.tsx b/apps/landing/src/app/(apps)/docs/page.tsx similarity index 100% rename from apps/landing/src/app/docs/page.tsx rename to apps/landing/src/app/(apps)/docs/page.tsx diff --git a/apps/landing/src/app/(apps)/layout.tsx b/apps/landing/src/app/(apps)/layout.tsx new file mode 100644 index 0000000..502835d --- /dev/null +++ b/apps/landing/src/app/(apps)/layout.tsx @@ -0,0 +1,38 @@ +import Image from 'next/image'; +import { Footer } from '@/components/shared/Footer'; + +export default function AppsLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {/* Scrollable Header (NOT sticky) */} +
+ +
+ + {children} + +
+ + ); +} diff --git a/apps/landing/src/app/_assets/1.jpg b/apps/landing/src/app/(landings)/_assets/1.jpg similarity index 100% rename from apps/landing/src/app/_assets/1.jpg rename to apps/landing/src/app/(landings)/_assets/1.jpg diff --git a/apps/landing/src/app/_assets/2.jpg b/apps/landing/src/app/(landings)/_assets/2.jpg similarity index 100% rename from apps/landing/src/app/_assets/2.jpg rename to apps/landing/src/app/(landings)/_assets/2.jpg diff --git a/apps/landing/src/app/_assets/3.jpg b/apps/landing/src/app/(landings)/_assets/3.jpg similarity index 100% rename from apps/landing/src/app/_assets/3.jpg rename to apps/landing/src/app/(landings)/_assets/3.jpg diff --git a/apps/landing/src/app/_assets/4.jpg b/apps/landing/src/app/(landings)/_assets/4.jpg similarity index 100% rename from apps/landing/src/app/_assets/4.jpg rename to apps/landing/src/app/(landings)/_assets/4.jpg diff --git a/apps/landing/src/app/_assets/5.jpg b/apps/landing/src/app/(landings)/_assets/5.jpg similarity index 100% rename from apps/landing/src/app/_assets/5.jpg rename to apps/landing/src/app/(landings)/_assets/5.jpg diff --git a/apps/landing/src/app/_assets/6.jpg b/apps/landing/src/app/(landings)/_assets/6.jpg similarity index 100% rename from apps/landing/src/app/_assets/6.jpg rename to apps/landing/src/app/(landings)/_assets/6.jpg diff --git a/apps/landing/src/app/_assets/7.jpg b/apps/landing/src/app/(landings)/_assets/7.jpg similarity index 100% rename from apps/landing/src/app/_assets/7.jpg rename to apps/landing/src/app/(landings)/_assets/7.jpg diff --git a/apps/landing/src/app/_assets/8.jpg b/apps/landing/src/app/(landings)/_assets/8.jpg similarity index 100% rename from apps/landing/src/app/_assets/8.jpg rename to apps/landing/src/app/(landings)/_assets/8.jpg diff --git a/apps/landing/src/app/_assets/9.jpg b/apps/landing/src/app/(landings)/_assets/9.jpg similarity index 100% rename from apps/landing/src/app/_assets/9.jpg rename to apps/landing/src/app/(landings)/_assets/9.jpg diff --git a/apps/landing/src/app/_assets/banatie-logo-horisontal.png b/apps/landing/src/app/(landings)/_assets/banatie-logo-horisontal.png similarity index 100% rename from apps/landing/src/app/_assets/banatie-logo-horisontal.png rename to apps/landing/src/app/(landings)/_assets/banatie-logo-horisontal.png diff --git a/apps/landing/src/app/_components/ApiExampleSection.tsx b/apps/landing/src/app/(landings)/_components/ApiExampleSection.tsx similarity index 100% rename from apps/landing/src/app/_components/ApiExampleSection.tsx rename to apps/landing/src/app/(landings)/_components/ApiExampleSection.tsx diff --git a/apps/landing/src/app/_components/BackgroundBlobs.tsx b/apps/landing/src/app/(landings)/_components/BackgroundBlobs.tsx similarity index 100% rename from apps/landing/src/app/_components/BackgroundBlobs.tsx rename to apps/landing/src/app/(landings)/_components/BackgroundBlobs.tsx diff --git a/apps/landing/src/app/_components/FinalCtaSection.tsx b/apps/landing/src/app/(landings)/_components/FinalCtaSection.tsx similarity index 100% rename from apps/landing/src/app/_components/FinalCtaSection.tsx rename to apps/landing/src/app/(landings)/_components/FinalCtaSection.tsx diff --git a/apps/landing/src/app/_components/GeminiSection.tsx b/apps/landing/src/app/(landings)/_components/GeminiSection.tsx similarity index 100% rename from apps/landing/src/app/_components/GeminiSection.tsx rename to apps/landing/src/app/(landings)/_components/GeminiSection.tsx diff --git a/apps/landing/src/app/_components/GlowEffect.tsx b/apps/landing/src/app/(landings)/_components/GlowEffect.tsx similarity index 100% rename from apps/landing/src/app/_components/GlowEffect.tsx rename to apps/landing/src/app/(landings)/_components/GlowEffect.tsx diff --git a/apps/landing/src/app/_components/HeroGlow.tsx b/apps/landing/src/app/(landings)/_components/HeroGlow.tsx similarity index 100% rename from apps/landing/src/app/_components/HeroGlow.tsx rename to apps/landing/src/app/(landings)/_components/HeroGlow.tsx diff --git a/apps/landing/src/app/_components/HeroSection.tsx b/apps/landing/src/app/(landings)/_components/HeroSection.tsx similarity index 100% rename from apps/landing/src/app/_components/HeroSection.tsx rename to apps/landing/src/app/(landings)/_components/HeroSection.tsx diff --git a/apps/landing/src/app/_components/HowItWorksSection.tsx b/apps/landing/src/app/(landings)/_components/HowItWorksSection.tsx similarity index 100% rename from apps/landing/src/app/_components/HowItWorksSection.tsx rename to apps/landing/src/app/(landings)/_components/HowItWorksSection.tsx diff --git a/apps/landing/src/app/_components/IntegrationsSection.tsx b/apps/landing/src/app/(landings)/_components/IntegrationsSection.tsx similarity index 100% rename from apps/landing/src/app/_components/IntegrationsSection.tsx rename to apps/landing/src/app/(landings)/_components/IntegrationsSection.tsx diff --git a/apps/landing/src/app/_components/KeyFeaturesSection.tsx b/apps/landing/src/app/(landings)/_components/KeyFeaturesSection.tsx similarity index 100% rename from apps/landing/src/app/_components/KeyFeaturesSection.tsx rename to apps/landing/src/app/(landings)/_components/KeyFeaturesSection.tsx diff --git a/apps/landing/src/app/_components/ProblemSolutionSection.tsx b/apps/landing/src/app/(landings)/_components/ProblemSolutionSection.tsx similarity index 100% rename from apps/landing/src/app/_components/ProblemSolutionSection.tsx rename to apps/landing/src/app/(landings)/_components/ProblemSolutionSection.tsx diff --git a/apps/landing/src/app/_components/PromptUrlsSection.tsx b/apps/landing/src/app/(landings)/_components/PromptUrlsSection.tsx similarity index 100% rename from apps/landing/src/app/_components/PromptUrlsSection.tsx rename to apps/landing/src/app/(landings)/_components/PromptUrlsSection.tsx diff --git a/apps/landing/src/app/_components/ShapeTheFutureSection.tsx b/apps/landing/src/app/(landings)/_components/ShapeTheFutureSection.tsx similarity index 100% rename from apps/landing/src/app/_components/ShapeTheFutureSection.tsx rename to apps/landing/src/app/(landings)/_components/ShapeTheFutureSection.tsx diff --git a/apps/landing/src/app/_components/WaitlistEmailForm.tsx b/apps/landing/src/app/(landings)/_components/WaitlistEmailForm.tsx similarity index 100% rename from apps/landing/src/app/_components/WaitlistEmailForm.tsx rename to apps/landing/src/app/(landings)/_components/WaitlistEmailForm.tsx diff --git a/apps/landing/src/app/_components/WaitlistPopup.tsx b/apps/landing/src/app/(landings)/_components/WaitlistPopup.tsx similarity index 100% rename from apps/landing/src/app/_components/WaitlistPopup.tsx rename to apps/landing/src/app/(landings)/_components/WaitlistPopup.tsx diff --git a/apps/landing/src/app/_components/index.ts b/apps/landing/src/app/(landings)/_components/index.ts similarity index 100% rename from apps/landing/src/app/_components/index.ts rename to apps/landing/src/app/(landings)/_components/index.ts diff --git a/apps/landing/src/app/(landings)/layout.tsx b/apps/landing/src/app/(landings)/layout.tsx new file mode 100644 index 0000000..231c7c3 --- /dev/null +++ b/apps/landing/src/app/(landings)/layout.tsx @@ -0,0 +1,38 @@ +import Image from 'next/image'; +import { Footer } from '@/components/shared/Footer'; + +export default function LandingsLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {/* Sticky Header */} +
+ +
+ + {children} + +
+ + ); +} diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/(landings)/page.tsx similarity index 100% rename from apps/landing/src/app/page.tsx rename to apps/landing/src/app/(landings)/page.tsx diff --git a/apps/landing/src/app/layout.tsx b/apps/landing/src/app/layout.tsx index 2524904..12673cc 100644 --- a/apps/landing/src/app/layout.tsx +++ b/apps/landing/src/app/layout.tsx @@ -1,9 +1,6 @@ import type { Metadata } from 'next'; import { Inter, Caveat } from 'next/font/google'; -import Image from 'next/image'; import Script from 'next/script'; -import { Footer } from '@/components/shared/Footer'; -import banatieLogo from './_assets/banatie-logo-horisontal.png'; import './globals.css'; const inter = Inter({ @@ -47,32 +44,7 @@ export default function RootLayout({
- {/* Header */} -
- -
- - {/* Page content */} {children} - -