270 lines
9.1 KiB
TypeScript
270 lines
9.1 KiB
TypeScript
'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 (
|
|
<DocPage
|
|
breadcrumbItems={[
|
|
{ label: 'Documentation', href: '/docs' },
|
|
{ label: 'API Reference', href: '/docs/api' },
|
|
{ label: 'Image Upload' },
|
|
]}
|
|
tocItems={tocItems}
|
|
nextSteps={{
|
|
links: [
|
|
{
|
|
href: '/docs/api/images',
|
|
title: 'Image Management',
|
|
description: 'Learn how to list, update, and delete uploaded images.',
|
|
accent: 'primary',
|
|
},
|
|
{
|
|
href: '/docs/api/advanced',
|
|
title: 'Advanced Generation',
|
|
description: 'Use uploaded images as references for generation.',
|
|
accent: 'secondary',
|
|
},
|
|
],
|
|
}}
|
|
>
|
|
{/* Hero Section */}
|
|
<Hero
|
|
title="Image Upload"
|
|
subtitle="Upload images for reference in generations or as standalone assets."
|
|
/>
|
|
|
|
{/* Overview */}
|
|
<section id="overview" className="mb-12">
|
|
<SectionHeader level={2} id="overview">
|
|
Overview
|
|
</SectionHeader>
|
|
<p className="text-gray-300 leading-relaxed mb-4">
|
|
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.
|
|
</p>
|
|
<TipBox variant="compact" type="info">
|
|
<strong>Tip:</strong> Use aliases like <InlineCode>@logo</InlineCode> to reference
|
|
uploaded images by name instead of UUID.
|
|
</TipBox>
|
|
</section>
|
|
|
|
{/* Endpoint */}
|
|
<section id="endpoint" className="mb-12">
|
|
<SectionHeader level={2} id="endpoint">
|
|
Upload Endpoint
|
|
</SectionHeader>
|
|
<EndpointCard
|
|
method="POST"
|
|
endpoint="/api/v1/images/upload"
|
|
baseUrl="https://api.banatie.app"
|
|
/>
|
|
<p className="text-gray-400 text-sm mt-4">
|
|
Requires <InlineCode>X-API-Key</InlineCode> header with your Project Key.
|
|
Content-Type must be <InlineCode>multipart/form-data</InlineCode>.
|
|
</p>
|
|
</section>
|
|
|
|
{/* Parameters */}
|
|
<section id="parameters" className="mb-12">
|
|
<SectionHeader level={2} id="parameters" className="mb-6">
|
|
Form Parameters
|
|
</SectionHeader>
|
|
<p className="text-gray-300 leading-relaxed mb-6">
|
|
Send parameters as <InlineCode>multipart/form-data</InlineCode>:
|
|
</p>
|
|
|
|
<Table
|
|
headers={['Parameter', 'Type', 'Required', 'Description']}
|
|
rows={formParameters.map((param) => [
|
|
<InlineCode key="name">{param.name}</InlineCode>,
|
|
<span key="type" className="text-cyan-400">{param.type}</span>,
|
|
<span key="required" className={param.required ? 'text-green-400' : 'text-gray-500'}>
|
|
{param.required ? 'Yes' : 'No'}
|
|
</span>,
|
|
param.description,
|
|
])}
|
|
/>
|
|
|
|
<div className="mt-6">
|
|
<CodeBlock
|
|
code={`curl -X POST https://api.banatie.app/api/v1/images/upload \\
|
|
-H "X-API-Key: YOUR_PROJECT_KEY" \\
|
|
-F "file=@logo.png" \\
|
|
-F "alias=@brand-logo" \\
|
|
-F 'meta={"tags": ["logo", "brand"]}'`}
|
|
language="bash"
|
|
filename="Example Request"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
{/* File Constraints */}
|
|
<section id="constraints" className="mb-12">
|
|
<SectionHeader level={2} id="constraints" className="mb-6">
|
|
File Constraints
|
|
</SectionHeader>
|
|
|
|
<Table
|
|
headers={['Constraint', 'Limit']}
|
|
rows={fileConstraints.map(([constraint, limit]) => [
|
|
constraint,
|
|
<InlineCode key="limit">{limit}</InlineCode>,
|
|
])}
|
|
/>
|
|
|
|
<div className="mt-6">
|
|
<TipBox variant="compact" type="warning">
|
|
<strong>File Size:</strong> Files larger than 5MB will be rejected with a 400 error.
|
|
Compress images before uploading if needed.
|
|
</TipBox>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Flow Association */}
|
|
<section id="flow-association" className="mb-12">
|
|
<SectionHeader level={2} id="flow-association" className="mb-6">
|
|
Flow Association
|
|
</SectionHeader>
|
|
<p className="text-gray-300 leading-relaxed mb-6">
|
|
Images can be associated with generation flows for organized workflows.
|
|
The <InlineCode>flowId</InlineCode> parameter controls this behavior:
|
|
</p>
|
|
|
|
<Table
|
|
headers={['flowId Value', 'Behavior']}
|
|
rows={flowIdBehavior.map(([value, behavior]) => [
|
|
<InlineCode key="value">{value}</InlineCode>,
|
|
behavior,
|
|
])}
|
|
/>
|
|
|
|
<div className="mt-6">
|
|
<CodeBlock
|
|
code={`# Associate with existing flow
|
|
curl -X POST https://api.banatie.app/api/v1/images/upload \\
|
|
-H "X-API-Key: YOUR_PROJECT_KEY" \\
|
|
-F "file=@reference.png" \\
|
|
-F "flowId=550e8400-e29b-41d4-a716-446655440000" \\
|
|
-F "flowAlias=@reference"`}
|
|
language="bash"
|
|
filename="Upload with Flow"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Response */}
|
|
<section id="response" className="mb-12">
|
|
<SectionHeader level={2} id="response" className="mb-4">
|
|
Response Format
|
|
</SectionHeader>
|
|
<p className="text-gray-300 leading-relaxed mb-4">
|
|
On success, the API returns a JSON object containing the uploaded image details.
|
|
</p>
|
|
|
|
<CodeBlock
|
|
code={`{
|
|
"success": true,
|
|
"data": {
|
|
"id": "7c4ccf47-41ce-4718-afbc-8c553b2c631a",
|
|
"projectId": "57c7f7f4-47de-4d70-9ebd-3807a0b63746",
|
|
"flowId": null,
|
|
"storageUrl": "https://cdn.banatie.app/default/my-project/img/7c4ccf47-41ce-4718-afbc-8c553b2c631a",
|
|
"mimeType": "image/png",
|
|
"fileSize": 45678,
|
|
"width": 512,
|
|
"height": 512,
|
|
"source": "uploaded",
|
|
"alias": "@brand-logo",
|
|
"focalPoint": null,
|
|
"meta": { "tags": ["logo", "brand"] },
|
|
"createdAt": "2025-11-28T10:00:00.000Z"
|
|
}
|
|
}`}
|
|
language="json"
|
|
filename="Success Response"
|
|
/>
|
|
|
|
<TipBox variant="compact" type="info">
|
|
<strong>Note:</strong> The <InlineCode>id</InlineCode> field equals the filename in storage (UUID).
|
|
Original filename is preserved in object metadata.
|
|
</TipBox>
|
|
</section>
|
|
|
|
{/* Error Codes */}
|
|
<section id="error-codes" className="mb-12">
|
|
<SectionHeader level={2} id="error-codes" className="mb-6">
|
|
Error Codes
|
|
</SectionHeader>
|
|
<p className="text-gray-300 leading-relaxed mb-6">
|
|
The API uses standard HTTP status codes and returns descriptive error messages.
|
|
</p>
|
|
|
|
<Table
|
|
headers={['Status', 'Code', 'Description']}
|
|
rows={errorCodes.map(([status, code, description]) => [
|
|
<InlineCode key="status" color="error">{status}</InlineCode>,
|
|
<InlineCode key="code">{code}</InlineCode>,
|
|
description,
|
|
])}
|
|
/>
|
|
</section>
|
|
</DocPage>
|
|
);
|
|
}
|