API Documentation

Generate AI images and videos with the Genova Platform. Use the REST API, WebSocket for real-time updates, or our browser extensions for automated generation.

API v1.0Base URL: autoflow-api.aboessa101.workers.dev

7 Models

Image & Video

~30s

Image Generation

~3min

Video (Fast)

REST + WS

Real-time Updates

Quick Start

1

Get Your API Key

Sign up and create an API key from Dashboard → API Keys. Your key starts with af_ and is shown only once.

2

Create a Generation Job

bash
curl -X POST https://autoflow-api.aboessa101.workers.dev/api/jobs \
  -H "X-API-Key: af_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "prompt": "A cat playing piano in a jazz club",
    "model": "imagen4",
    "aspectRatio": "landscape",
    "count": 1
  }'
json
{
  "success": true,
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "queuePosition": 1,
  "estimatedTime": 30
}
3

Check Status & Download

bash
# Poll status
curl https://autoflow-api.aboessa101.workers.dev/api/jobs/JOB_ID \
  -H "X-API-Key: af_your_api_key_here"

# Download when completed
curl https://autoflow-api.aboessa101.workers.dev/api/jobs/JOB_ID/download \
  -H "X-API-Key: af_your_api_key_here"

Authentication

All API requests require authentication. Two methods are supported:

Recommended

API Key

Send in the X-API-Key header.

Alternative

JWT Bearer Token

Send in the Authorization: Bearer <token> header.

bash
# API Key (recommended for server-to-server)
curl -H "X-API-Key: af_your_api_key_here" ...

# JWT Token (used by web dashboard and extensions)
curl -H "Authorization: Bearer eyJhbGciOi..." ...

Available Models

Genova supports 7 AI models across two platforms: Google Flow (images & videos) and Freepik Pikaso (images).

Image Models

imagen4Imagen 4
Google Flow

Google’s latest image generation model. Best overall quality and prompt adherence. Supports reference images.

~30s ExcellentAspect: landscape, portrait, squareCount: 1-4
nano_banana_proNano Banana Pro
Google Flow

Fast community model optimized for artistic styles. Good for creative/stylized outputs.

~20s GoodAspect: landscape, portrait, squareCount: 1-4
nano_banana2Nano Banana 2
Google Flow

Updated community model with improved realism. Good for photo-realistic generations.

~20s GoodAspect: landscape, portrait, squareCount: 1-4

Video Models

veo3_fastVEO 3 Fast
Google Flow

Google’s VEO 3 in fast mode. Generates high-quality videos with good prompt adherence in under 3 minutes.

~2-3 min ExcellentAspect: landscape, portrait, squareCount: 1
veo3_qualityVEO 3 Quality
Google Flow

VEO 3 at maximum quality. Slower but produces cinema-grade video output with superior detail.

~5-8 min PremiumAspect: landscape, portrait, squareCount: 1
veo2_fastVEO 2 Fast
Google Flow

Previous generation VEO model. Fastest video generation, ideal for drafts and rapid iteration.

~1-2 min GoodAspect: landscape, portrait, squareCount: 1

Freepik Model

freepikFreepik Pikaso AI
Freepik

Freepik's Pikaso AI image generator. Supports 7 aspect ratios, 2 resolutions, up to 4 images per generation, and 6 reference image modes for style-guided generation.

~20-40s Good7 aspect ratios1K / 2K resolutionCount: 1-4

Freepik-specific settings:

resolution — "1K" or "2K"
referenceImages.mode — see Reference Images

Dimensions & Aspect Ratios

Google Flow Models

(imagen4, nano_banana_pro, nano_banana2, veo3_*, veo2_*)
ValueRatioBest For
landscape16:9Desktop wallpapers, YouTube thumbnails, presentations
portrait9:16Mobile wallpapers, Instagram stories, TikTok
square1:1Social media posts, profile pictures, thumbnails

Pass as aspectRatio in the job settings.

Freepik Model

(model: "freepik")
ValueDescriptionBest For
1:1SquareSocial media, icons
4:3StandardPresentations, blog images
3:4PortraitPosters, book covers
16:9WidescreenDesktop backgrounds, banners
9:16Tall / StoriesPhone wallpapers, stories
3:2Photo landscapePhotography-style images
2:3Photo portraitPortrait photography

Resolution Options

1KStandard resolution (default)
2KHigh quality, larger file size

Reference Images

Upload reference images to guide the AI generation. Images should be sent as base64-encoded strings. The API normalizes them automatically.

Request Format

json
{
  "type": "image",
  "prompt": "A sunset over mountains",
  "model": "imagen4",
  "referenceImages": {
    "mode": "ingredients",
    "images": [
      {
        "name": "reference_1.jpg",
        "data": "data:image/jpeg;base64,/9j/4AAQSkZ...",
        "mimeType": "image/jpeg"
      }
    ]
  }
}

The object form above is preferred. A bare string ("data:image/...;base64,..." or plain base64) is still accepted and gets an auto-generated name.

Size limit: 32MB total across all reference images in one request. Larger payloads are rejected with 413 plus receivedBytes, before any credit is spent. Resizing to 1024px on the longest edge keeps a photo well under 1MB.

Prompt limit: 500 characters. Longer prompts are rejected with 400 and receivedChars.

Stored outside the job row. Images are written to object storage and the job keeps only a pointer, so large payloads no longer fail the insert. Fetch them back with GET /api/jobs/:id/references.

Deleted with the job. Removing a job also removes its stored reference images.

Failed jobs are refunded. A job that ends in failed returns its credit automatically, including worker-side capture failures.

Consistent Characters (tag mode)

Keep the same cast across many scenes — for cartoons, storyboards and series.

First build the character inside Flow (Characters tab — image plus optional voice). Then reference it from a prompt with @name. The extension opens Flow's asset picker, selects that character and presses Add to Prompt, so the asset becomes a real prompt chip — exactly what you get by hand. The same asset is reused in every scene, which is what keeps the character consistent.

json
{
  "type": "image",
  "prompt": "@\"test Character\" man in home",
  "model": "nano_banana2",
  "referenceImages": {
    "mode": "tag",
    "characters": ["test Character"]
  }
}

The asset must already exist in Flow. Only the name is needed — pass characters: ["test Character"]. No image upload is involved, so a character built in Flow (with its voice) is referenced as-is.

Quote names that contain spaces. A bare @test Character stops at the space and resolves to test. Write @"test Character" or @[test Character] instead.

Names are matched on the picker row label (trimmed, case-insensitive) and must be unique. There is no "closest match" fallback — a name that does not resolve is reported rather than silently swapped for another character.

@me is your avatar. It resolves against Flow's Avatar tab and needs no entry in characters.

Validated up front. A mention with no matching character is rejected with 400 plus the missing names, so a scene never renders silently without its cast.

Works for video too. Send "type": "video" with the same tag payload to animate the same cast.

Building a Full Cartoon

Build the cast once in Flow, then submit one job per scene reusing the same characters array — every scene resolves to the same assets.

javascript
// Names must match the assets already in your Flow project.
const characters = ['sara girl', 'ahmed boy', 'magic forest'];

// Quote any name that contains a space.
const scenes = [
  '@"sara girl" walks into @"magic forest" at sunrise',
  '@"sara girl" and @"ahmed boy" find a glowing lantern',
  '@"ahmed boy" holds the lantern high, @"magic forest" lights up',
];

for (const prompt of scenes) {
  const res = await fetch('https://autoflow-api.aboessa101.workers.dev/api/jobs', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      type: 'image',            // or 'video'
      prompt,
      model: 'nano_banana2',
      aspectRatio: 'landscape',
      referenceImages: { mode: 'tag', characters },
    }),
  });

  const { jobId } = await res.json();
  console.log('queued scene:', jobId);
}

Scenes are queued in order and processed one at a time by the extension worker. Track progress over the WebSocket, or poll GET /api/jobs.

Reference Modes

ModePlatformDescription
ingredientsFlowCombines elements from your reference images into the generated image
framesFlowVideo only. Start / End keyframes (slot 0 = Start, slot 1 = End)
tagFlowNamed characters referenced inline as @name in the prompt. Keeps a cast consistent across scenes
styleFreepikApplies the artistic style of the reference to the generation
characterFreepikUses a character/person from the reference in the output
elementFreepikIncorporates specific visual elements from the reference
colorFreepikMatches the color palette of the reference image
effectsFreepikApplies visual effects (lighting, texture) from the reference
cameraFreepikMatches the camera angle and perspective of the reference

Image Tools

Optimize, inspect and cut out images without creating a generation job. Backed by Cloudflare Images — the free tier covers 5,000 unique transformations per calendar month, and repeat requests for the same image and parameters inside a month are not re-billed.

POST/api/images/optimizeShrink an image
json
{
  "image": "data:image/png;base64,iVBORw0KGgo...",
  "width": 1024,
  "format": "image/webp",
  "quality": 85
}

Only image is required. Defaults are width: 1024, format: image/webp, quality: 85. Allowed formats: image/webp, image/avif, image/jpeg, image/png.

Response

json
{
  "success": true,
  "image": "data:image/webp;base64,UklGRg...",
  "optimized": true,
  "originalBytes": 915444,
  "optimizedBytes": 172774,
  "savedBytes": 742670,
  "savedPercent": 81
}

Never returns a larger image. If re-encoding would grow the file, the original is returned with optimized: false.

Input limit: 20MB. Larger inputs are rejected with 413; an image that cannot be processed returns 422.

POST/api/images/infoRead metadata
json
// request
{ "image": "data:image/png;base64,iVBORw0KGgo..." }

// response
{
  "success": true,
  "info": { "fileSize": 915443, "width": 1600, "height": 1200, "format": "image/png" }
}

Metadata reads are not billed as transformations.

POST/api/images/remove-backgroundCut out a subject

You must supply the mask. Cloudflare has no segmentation model, so this endpoint composites a mask you generate — it does not detect the subject for you. Generating the mask is free and runs locally (see below).

json
{
  "image": "data:image/png;base64,iVBORw0KGgo...",
  "mask":  "data:image/png;base64,iVBORw0KGgo..."
}

The mask must match the image dimensions: opaque where the subject is, transparent elsewhere. Output is always PNG so the cutout keeps its alpha channel.

Generating the mask for free

Run a segmentation model client-side with @huggingface/transformers (Apache-2.0). No server cost and the image never leaves the device until you send it.

javascript
import { pipeline } from '@huggingface/transformers';

// Runs in the browser / extension via WebGPU or WASM.
const segmenter = await pipeline('background-removal', 'briaai/RMBG-1.4');
const [{ mask }] = await segmenter(imageUrl);

// Send the mask alongside the original image.
const res = await fetch('https://autoflow-api.aboessa101.workers.dev/api/images/remove-background', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ image: originalDataUrl, mask: maskDataUrl }),
});

const { image } = await res.json(); // PNG cutout with transparency

Avoid @imgly/background-removal in a commercial product: it is AGPL-3.0, which requires publishing your source when users interact with a modified version over a network.

Optimize while creating a job

Add optimizeImage to a job request to shrink every reference image before it is stored. This runs before the size check, so it can bring an oversized set of photos under the limit instead of being rejected.

json
{
  "type": "image",
  "prompt": "a cozy reading nook",
  "model": "nano_banana2",
  "optimizeImage": true,
  "referenceImages": {
    "mode": "ingredients",
    "images": [{ "name": "room.jpg", "data": "data:image/jpeg;base64,..." }]
  }
}

Pass an object for control: "optimizeImage": { "width": 768, "format": "image/webp", "quality": 80 }. Optimization is best-effort — if a transform fails the original image is used and the job still runs.

API Reference

Base URL: https://autoflow-api.aboessa101.workers.dev

POST/api/jobsCreate Generation Job

Creates a new image or video generation job. Deducts 1 credit.

ParameterTypeReqDescription
typestringYes"image" or "video"
promptstringYesText description (max 500 chars)
modelstringNoSee Available Models. Default: "imagen4"
aspectRatiostringNoFlow: "landscape" / "portrait" / "square". Freepik: "1:1" / "4:3" / "3:4" / "16:9" / "9:16" / "3:2" / "2:3". Default: "landscape"
countnumberNoNumber of items (1-4). Videos always 1. Default: 1
qualitystringNoFreepik only: "1K" or "2K". Default: "1K"
referenceImagesobjectNo{ images: string[], mode: string }. See Reference Images section
prioritynumberNoQueue priority (higher = sooner). Default: 0

Examples:

json
// Image with Imagen 4
{
  "type": "image",
  "prompt": "A futuristic cityscape at sunset",
  "model": "imagen4",
  "aspectRatio": "landscape",
  "count": 2
}

// Video with VEO 3
{
  "type": "video",
  "prompt": "A drone flyover of a coral reef",
  "model": "veo3_fast",
  "aspectRatio": "landscape"
}

// Freepik with reference image
{
  "type": "image",
  "prompt": "A portrait in this style",
  "model": "freepik",
  "aspectRatio": "1:1",
  "count": 4,
  "quality": "2K",
  "referenceImages": {
    "images": ["data:image/jpeg;base64,..."],
    "mode": "style"
  }
}
GET/api/jobs/:idGet Job Status

Retrieve the full details and current status of a generation job.

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "image",
  "status": "completed",
  "prompt": "A cat playing piano in a jazz club",
  "settings": {
    "model": "imagen4",
    "aspectRatio": "landscape",
    "count": 1
  },
  "result_url": "generated/user-id/job-id/result.png",
  "result_urls": null,
  "created_at": "2025-04-02T10:30:00Z",
  "started_at": "2025-04-02T10:30:02Z",
  "completed_at": "2025-04-02T10:30:32Z",
  "processing_time": 30,
  "file_size": 1048576
}
GET/api/jobsList Jobs

List your generation jobs with optional filtering and pagination.

Query ParamTypeDescription
statusstringFilter: "pending", "queued", "processing", "completed", "failed"
limitnumberMax results per page (default: 50)
offsetnumberPagination offset (default: 0)
json
{
  "jobs": [
    { "id": "...", "type": "image", "status": "completed", "prompt": "...", ... },
    { "id": "...", "type": "video", "status": "processing", "prompt": "...", ... }
  ],
  "total": 42
}
GET/api/jobs/:id/downloadDownload Result

Get a signed download URL for a completed job. Redirects to the file. Only works for jobs with status completed.

bash
curl -L https://autoflow-api.aboessa101.workers.dev/api/jobs/JOB_ID/download \
  -H "X-API-Key: af_your_api_key_here" \
  -o result.png
DELETE/api/jobs/:idCancel Job

Cancel a pending or queued job. Credits are refunded if the job hasn't started processing. Returns { "success": true }.

API Key Management

POST
/api/keys

Create a new API key. Body: { "name": "My Key" }. Returns the full key (shown only once).

GET
/api/keys

List all active (non-revoked) API keys with prefix and metadata.

DELETE
/api/keys/:id

Permanently revoke an API key. Cannot be undone.

User & Statistics

GET
/api/user/me

Get your profile: id, email, name, subscription plan/status, credits remaining/used.

PATCH
/api/user/me

Update profile: { "name": "New Name" }

GET
/api/user/stats

Generation statistics: total/completed/failed/active jobs, image/video counts, credits remaining.

WebSocket (Real-time Updates)

Connect via WebSocket to receive real-time job status updates instead of polling. The dashboard and extensions both use this for instant notifications.

User Connection (Dashboard)

javascript
const ws = new WebSocket(
  'wss://autoflow-api.aboessa101.workers.dev/ws/user?userId=YOUR_USER_ID'
);

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log(msg.type, msg);
  // msg.type can be:
  //   "welcome"       — connection confirmed
  //   "job_started"   — extension picked up your job
  //   "job_progress"  — progress update with percentage
  //   "job_completed" — job done, includes resultUrl
  //   "job_failed"    — job failed, includes error message
};

Message Types

TypeDirectionFields
welcomeServer → Client{ type, userId }
job_startedServer → Client{ type, jobId }
job_progressServer → Client{ type, jobId, progress, message }
job_completedServer → Client{ type, jobId, resultUrl, resultUrls }
job_failedServer → Client{ type, jobId, error }
pingClient → Server{ type: "ping" } — keep-alive
pongServer → Client{ type: "pong" } — heartbeat reply

Extension Connection

Browser extensions connect to a separate endpoint and receive job assignments:

javascript
// Extension WebSocket (used internally by Flow/Freepik extensions)
const ws = new WebSocket(
  'wss://autoflow-api.aboessa101.workers.dev/ws/extension' +
  '?userId=USER_ID&token=JWT_TOKEN&extensionType=flow'
  // extensionType: "flow" or "freepik"
);

// Extension receives:  new_job (assigned work)
// Extension sends:     job_progress, job_completed, job_failed, request_job

Job Lifecycle

pending
queued
processing
completed
pendingJob created, waiting for an available extension to pick it up.
queuedJob is in the queue and will be assigned to the next idle extension of the matching type (Flow or Freepik).
processingAn extension is actively generating content. Progress updates are sent via WebSocket. Stuck jobs are auto-failed after 15 minutes.
completedGeneration finished. Result is uploaded to R2 storage. Use the download endpoint to retrieve it.
failedGeneration failed. Check error_message for details. Jobs queued for 30+ minutes without assignment are auto-failed.

Rate Limits

PlanRequests/minConcurrent JobsMonthly Credits
Free10250
Starter605500
Pro100102,000
Business3002510,000

When rate limited, the API returns 429 Too Many Requests with a Retry-After header.

Error Codes

CodeDescriptionResolution
200OKRequest succeeded
201CreatedResource created successfully (job, API key)
400Bad RequestCheck required parameters: type, prompt are required
401UnauthorizedVerify your API key or JWT token is valid and not expired
402Payment RequiredInsufficient credits. Upgrade your plan or purchase more credits
403ForbiddenYou don't have permission for this resource
404Not FoundJob or resource doesn't exist. Check the ID
429Rate LimitedWait and retry. Check Retry-After header
500Server ErrorInternal error — retry the request

Error Response Format

json
{
  "error": "Missing required fields",
  "details": "prompt is required"
}

Browser Extensions

Genova uses Chrome extensions as generation workers. Each extension connects to the platform via WebSocket, receives job assignments, and uploads results automatically.

Flow Image Automator

Handles all Google Flow models (Imagen 4, Nano Banana, VEO 2/3). Captures generated media from the Flow interface and uploads to R2.

Models: imagen4, nano_banana_pro, nano_banana2, veo3_fast, veo3_quality, veo2_fast

Platform: flow.google.com

Genova Images (Freepik)

Handles Freepik Pikaso AI model. Supports 6 reference image modes, 7 aspect ratios, and 2 resolution options.

Model: freepik

Platform: freepik.com/pikaso

How it works: When you create a job via the API or dashboard, the Job Manager routes it to the correct extension type based on the model. Jobs with model: "freepik" go to the Freepik extension; all others go to Flow. The extension generates the content in the background, uploads the result to cloud storage, and reports completion.