8.3 KiB
Image Upload & Management API
Upload images and manage your image library. For generation, see image-generation.md.
All endpoints require Project Key authentication via X-API-Key header.
Upload Image
POST /api/v1/images/upload
Upload an image file with optional alias and flow association.
Content-Type: multipart/form-data
Form Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | Image file (PNG, JPEG, WebP) |
alias |
string | No | Project-scoped alias (e.g., @logo) |
flowId |
string | No | Flow UUID to associate with |
flowAlias |
string | No | Flow-scoped alias (requires flowId) |
meta |
string | No | JSON string with custom metadata |
File Constraints:
| Constraint | Limit |
|---|---|
| Max file size | 5MB |
| Supported formats | PNG, JPEG, JPG, WebP |
| MIME types | image/png, image/jpeg, image/webp |
Example Request (curl):
curl -X POST http://localhost:3000/api/v1/images/upload \
-H "X-API-Key: YOUR_PROJECT_KEY" \
-F "file=@logo.png" \
-F "alias=@brand-logo" \
-F 'meta={"tags": ["logo", "brand"]}'
Response: 201 Created
{
"success": true,
"data": {
"id": "7c4ccf47-41ce-4718-afbc-8c553b2c631a",
"projectId": "57c7f7f4-47de-4d70-9ebd-3807a0b63746",
"flowId": null,
"storageKey": "default/project-id/uploads/2025-11/logo.png",
"storageUrl": "http://localhost:9000/banatie/default/project-id/uploads/logo.png",
"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"
}
}
flowId Behavior
| Value | Behavior |
|---|---|
| Not provided | Auto-generate pendingFlowId, lazy flow creation |
null |
No flow association |
"uuid" |
Associate with specified flow |
Upload with Flow
# Associate with existing flow
curl -X POST .../images/upload \
-F "file=@reference.png" \
-F "flowId=flow-123" \
-F "flowAlias=@reference"
List Images
GET /api/v1/images
List all images with filtering and pagination.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
flowId |
string | - | Filter by flow UUID |
source |
string | - | Filter by source: generated, uploaded |
alias |
string | - | Filter by exact alias match |
limit |
number | 20 |
Results per page (max: 100) |
offset |
number | 0 |
Pagination offset |
includeDeleted |
boolean | false |
Include soft-deleted records |
Example:
GET /api/v1/images?source=uploaded&limit=10
Response:
{
"success": true,
"data": [
{
"id": "7c4ccf47-...",
"storageUrl": "http://...",
"source": "uploaded",
"alias": "@brand-logo",
"width": 512,
"height": 512,
"createdAt": "2025-11-28T10:00:00.000Z"
}
],
"pagination": {
"limit": 10,
"offset": 0,
"total": 25,
"hasMore": true
}
}
Get Image
GET /api/v1/images/:id_or_alias
Get a single image by UUID or alias.
Path Parameter:
id_or_alias- Image UUID or@alias
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
flowId |
string | Flow context for alias resolution |
Examples:
# By UUID
GET /api/v1/images/7c4ccf47-41ce-4718-afbc-8c553b2c631a
# By project alias
GET /api/v1/images/@brand-logo
# By technical alias (requires flowId)
GET /api/v1/images/@last?flowId=flow-123
# By flow alias
GET /api/v1/images/@hero?flowId=flow-123
Response:
{
"success": true,
"data": {
"id": "7c4ccf47-41ce-4718-afbc-8c553b2c631a",
"projectId": "57c7f7f4-47de-4d70-9ebd-3807a0b63746",
"flowId": null,
"storageKey": "default/project-id/uploads/2025-11/logo.png",
"storageUrl": "http://localhost:9000/banatie/.../logo.png",
"mimeType": "image/png",
"fileSize": 45678,
"width": 512,
"height": 512,
"source": "uploaded",
"alias": "@brand-logo",
"focalPoint": null,
"fileHash": null,
"generationId": null,
"meta": { "tags": ["logo", "brand"] },
"createdAt": "2025-11-28T10:00:00.000Z",
"updatedAt": "2025-11-28T10:00:00.000Z",
"deletedAt": null
}
}
Update Image Metadata
PUT /api/v1/images/:id_or_alias
Update image metadata (focal point, custom metadata).
Request Body:
| Parameter | Type | Description |
|---|---|---|
focalPoint |
object | Focal point: { x: 0.0-1.0, y: 0.0-1.0 } |
meta |
object | Custom metadata |
Example:
// PUT /api/v1/images/@brand-logo
{
"focalPoint": { "x": 0.5, "y": 0.3 },
"meta": {
"description": "Updated brand logo",
"tags": ["logo", "brand", "2025"]
}
}
Response: Updated image object.
Note: Alias assignment has its own dedicated endpoint.
Assign Alias
PUT /api/v1/images/:id_or_alias/alias
Assign or remove a project-scoped alias.
Request Body:
// Assign alias
{ "alias": "@new-logo" }
// Remove alias
{ "alias": null }
Override Behavior:
- If another image has this alias, it loses the alias
- The new image gets the alias
- Old image is preserved, just unlinked
Example:
curl -X PUT http://localhost:3000/api/v1/images/7c4ccf47-.../alias \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"alias": "@primary-logo"}'
Delete Image
DELETE /api/v1/images/:id_or_alias
Permanently delete an image and its storage file.
Behavior:
- Hard delete - image record permanently removed
- Storage file deleted from MinIO
- Cascading updates:
- Related generations:
outputImageIdset to null - Flow aliases: image removed from flow's aliases
- Referenced images: removed from generation's referencedImages
- Related generations:
Response: 200 OK
{
"success": true,
"message": "Image deleted"
}
Warning: This cannot be undone. The image file is permanently removed.
Image Response Fields
| Field | Type | Description |
|---|---|---|
id |
string | Image UUID |
projectId |
string | Project UUID |
flowId |
string | Associated flow UUID (null if none) |
storageKey |
string | Internal storage path |
storageUrl |
string | Direct URL to access image |
mimeType |
string | Image MIME type |
fileSize |
number | File size in bytes |
width |
number | Image width in pixels |
height |
number | Image height in pixels |
source |
string | "generated" or "uploaded" |
alias |
string | Project-scoped alias (null if none) |
focalPoint |
object | { x, y } coordinates (0.0-1.0) |
fileHash |
string | SHA-256 hash for deduplication |
generationId |
string | Source generation UUID (if generated) |
meta |
object | Custom metadata |
createdAt |
string | ISO timestamp |
updatedAt |
string | ISO timestamp |
deletedAt |
string | Soft delete timestamp (null if active) |
Accessing Images
Use storageUrl for direct image access:
<img src="http://localhost:9000/banatie/.../image.png" />
For public CDN access, see Live URLs.
Storage Organization
Images are organized in MinIO storage:
bucket/
{orgId}/
{projectId}/
uploads/ # Uploaded images
2025-11/
image.png
generated/ # AI-generated images
2025-11/
gen_abc123.png
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 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 |
| 404 | IMAGE_NOT_FOUND |
Image or alias doesn't exist |
| 404 | ALIAS_NOT_FOUND |
Alias doesn't resolve to any image |
See Also
- Basic Generation - Generate images
- Advanced Generation - References, aliases, flows
- Live URLs - CDN and public access