Adflow is an AI-native ad creative builder. Your agent connects via MCP (Model Context Protocol) to create design systems, build multi-scene projects, and generate AI imagery — all from natural language. This page documents every endpoint, schema, and skill your agent needs, plus a reference for the editor's creative features — vector expressions, guided physics, and the full capability map.
generate_image — create AI backgrounds, then attach to scenes via update
MCP Server Setup
Add the Adflow MCP server to your agent's configuration. You'll need an API key from the Admin panel.
Hosted server (recommended — zero-install)
Nothing to clone, no npm, no npx. Point your agent at the hosted endpoint and pass your API key as a header. This is the easiest way to connect — the server runs on adflow.design.
Your key authenticates every request and attributes usage/credits to your account — a missing or invalid key returns 401. The hosted server exposes the exact same tools as the local methods below.
Local server (offline / dev only)
Only needed if you're running offline or hacking on the server itself — most people should use the hosted URL above. You'll need the mcp-server/ folder (from the repo or a shared tarball) and Node 18+.
First install its dependencies:
cd mcp-server && npm install
Then point your agent at the server's absolute path and pass your key via the environment. ADFLOW_API_KEY is required; ADFLOW_URL is optional (defaults to https://adflow.design).
Replace /absolute/path/to/mcp-server/index.js with the real path on your machine (e.g. /Users/you/adflow/mcp-server/index.js). A published npx adflow-mcp package is coming soon — it is not on npm yet, so don't rely on it today.
Authentication reference
Every request is authenticated with your Adflow API key. Create keys in Admin → API Keys. How you supply the key depends on the method:
X-API-Key header
Hosted server (and any direct REST call). The key travels as an HTTP header on each request.
ADFLOW_API_KEY env
Local stdio server — required. The mcp-server/index.js process reads it from the environment.
ADFLOW_URL env
Local stdio server — optional. Overrides the API base URL (defaults to https://adflow.design).
Authorization: Bearer
Supabase JWT token for browser sessions.
MCP Endpoints
27 tools available via the MCP server. All return JSON. You call these by tool name (not by HTTP verb) — the coloured badge below each tool indicates the HTTP method of the REST endpoint it wraps, for reference when using the Direct API Fallback.
GET list_design_systems
List all design systems you have access to.
No parameters. Returns an array of full design system objects.
POST create_design_system
Create a new design system. All scenes inherit colours, fonts, logo, and layout from here.
Param
Type
Description
name
string
required
Display name (e.g. "Acme Corp")
primaryColor
hex
required
Primary brand colour
secondaryColor
hex
optional
Secondary brand colour
darkColor
hex
optional
Dark colour (default #111111)
lightColor
hex
optional
Light colour (default #ffffff)
fontHeadline
string
optional
Headline font stack
fontBody
string
optional
Body font stack
fontImport
URL
optional
Google Fonts import URL
fontH1–fontCta
string
optional
Per-element font overrides
h1Weight–ctaWeight
string
optional
Font weights (e.g. "800")
h1Transform–ctaTransform
string
optional
"none" or "uppercase"
h1LetterSpacing–ctaLetterSpacing
string
optional
CSS letter-spacing
ctaRadius
string
optional
CTA border-radius multiplier
logoSvg
URL
optional
Logo SVG URL
logoPosition
string
optional
9-grid position (e.g. "top-left")
logoScale
number
optional
Logo size (100 = default)
contentPosition
string
optional
"top", "middle", or "bottom"
contentAlign
string
optional
"left" or "center"
ctaAlign
string
optional
"left" or "center"
disclaimer
string
optional
Legal disclaimer text
globalGenPrompt
string
optional
Default AI prompt prefix
PATCH update_design_system
Update any properties on an existing design system.
Param
Type
Description
id
string
required
Design system slug (e.g. "acme-corp")
data
object
required
Key-value pairs to update (see full schema below)
GET list_projects
List all projects with metadata.
No parameters. Returns id, filename, name, designSystemId, sceneCount, savedAt.
GET get_project
Get full project data including all scenes.
Param
Type
Description
id
string
required
Project UUID
POST create_project
Create a new project with scenes. Colours, layout, and logo position are inherited from the design system automatically.
Param
Type
Description
name
string
required
Project name (e.g. "June Campaign")
designSystem
string
required
Design system slug
format
enum
optional
Active format: square, portrait, vertical, landscape, wide
scenes
array
required
Array of scene objects (see below)
Scene object
Field
Type
Description
h1
string
required
Headline text
h2
string
optional
Supporting text
h3
string
optional
Third line of text
cta
string
optional
CTA button text
bgType
enum
optional
colour, gradient, or image
bgColor
hex
optional
Background colour (default: DS Dark)
bgImage
URL
optional
Background image URL
bgGradientFrom
hex
optional
Gradient start colour
bgGradientTo
hex
optional
Gradient end colour
bgGradientAngle
number
optional
Gradient angle degrees (default 180)
textColor
hex
optional
Text colour (default: DS Light)
ctaBgColor
hex
optional
CTA bg (default: DS Primary)
ctaTextColor
hex
optional
CTA text (default: DS Light)
contentPosition
enum
optional
top, middle, bottom
contentAlign
enum
optional
left or center
logoPosition
string
optional
9-grid position (e.g. "top-left")
overlayType
enum
optional
none, fill, gradient
overlayColour
hex
optional
Overlay colour
overlayOpacity
number
optional
Overlay opacity 0–1
notes
string
optional
Description / AI image prompt
duration
number
optional
Seconds (default 3)
audioUrl
URL
optional
Audio URL (use upload_audio)
audioFileName
string
optional
Audio filename for display
audioPlayMode
enum
optional
loop, once, fade
audioVolume
number
optional
Volume 0–100 (default 100)
audioOffset
number
optional
Start offset in ms
audioCropStart
number
optional
Trim start in ms
audioCropEnd
number
optional
Trim end in ms
audioFadeOut
number
optional
Fade out duration in ms
PUT update_project
Update an existing project. Fetch the project first, modify it, then pass the full object back.
Param
Type
Description
id
string
required
Project UUID
filename
string
required
Project filename
project
object
required
Full project object
DELETE delete_project
Permanently delete a project.
Param
Type
Description
id
string
required
Project UUID
POST generate_image
Generate an AI image for use as a scene background.
Param
Type
Description
prompt
string
required
Image generation prompt
filename
string
optional
Output filename
model
enum
optional
AI model (see table below)
width
number
optional
Width in px (default 2160)
height
number
optional
Height in px (default 2160)
Available models
gpt-image-1
ChatGPT Image v2 (default, best quality)
flux-dev
Flux Dev (fast)
flux-pro
Flux Pro
imagen4
Google Imagen 4
imagen4-fast
Google Imagen 4 Fast
nano-banana-pro
Nano Banana Pro
ideogram-v3
Ideogram v3
recraft-v3
Recraft V3
recraft-v3-transparent
Recraft V3 (transparent background PNG)
GET list_generations
Browse generated images, optionally scoped to a design system (client). Non-admins always see only images they have access to.
Param
Type
Description
designSystemId
string
required
Design system slug (e.g. "beau-brummell")
POST upload_image
Upload an image from a URL to Blob storage for use as a scene background.
Param
Type
Description
url
string
required
Public URL of the image
filename
string
optional
Filename for the stored image
POST outpaint_image
Expand an image's edges using AI outpainting. The source image is downloaded and sent as image data. Default model is fal-ai/bria/expand (fal-ai/flux-2-pro/outpaint also available). At least one expand_* value must be greater than 0.
Param
Type
Description
image_url
string
required
Public URL of the source image (downloaded and sent as image data)
expand_top
number
optional
Pixels to expand at top
expand_bottom
number
optional
Pixels to expand at bottom
expand_left
number
optional
Pixels to expand at left
expand_right
number
optional
Pixels to expand at right
prompt
string
optional
Hint for what to paint into the expanded area
model
enum
optional
fal-ai/bria/expand (default) or fal-ai/flux-2-pro/outpaint
filename
string
optional
Output filename (default: extended.png)
design_system_id
string
optional
Design system slug to scope storage to a client
POST generate_vector
Generate a clean editable SVG icon/shape via fal.ai (Recraft V4.1).
Param
Type
Description
prompt
string
required
Description of the SVG to generate
model
string
optional
fal.ai model (default: recraft-v4.1)
filename
string
optional
Output filename
POST duplicate_project
Duplicate a project (creates a copy with "(Copy)" suffix).
Param
Type
Description
id
string
required
Project UUID to duplicate
POST upload_audio
Upload an audio file from a URL for use as scene audio. Returns a Blob URL.
Param
Type
Description
url
string
required
Public URL of audio file (mp3, wav, ogg, aac, m4a)
filename
string
optional
Filename for stored audio
DELETE delete_design_system
Delete a design system (cannot delete "default").
Param
Type
Description
id
string
required
Design system slug to delete
POST render_video
Start a server-side MP4 render of a composition. Renders the supplied HTML via AWS and returns a renderId + executionArn — poll get_render_progress with the executionArn until status is SUCCEEDED to get the video URL.
Param
Type
Description
html
string
required
Full composition HTML to render
width
number
required
Output width in pixels
height
number
required
Output height in pixels
fps
number
optional
Frames per second (default 30)
quality
string
optional
Render quality (default "high")
format
string
optional
Output format (default "mp4")
GET get_render_progress
Poll the progress of a video render started with render_video. When status is SUCCEEDED, videoUrl holds a signed download URL (valid ~1 hour).
Param
Type
Description
executionArn
string
required
executionArn returned by render_video
filename
string
optional
Download filename for the signed URL (default: output.mp4)
POST render_screenshot
Render composition HTML to a PNG and return the image. Max dimension 4096px. To persist it to a public URL, pass a data URI to save_render.
Param
Type
Description
html
string
required
Full composition HTML to screenshot
width
number
required
Output width in pixels (max 4096)
height
number
required
Output height in pixels (max 4096)
POST save_render
Save a rendered image (base64 data URI) to storage and return a public URL. Use to persist a PNG produced by render_screenshot or an in-app export.
Param
Type
Description
dataUri
string
required
Base64 data URI, e.g. "data:image/png;base64,..."
filename
string
optional
Output filename (default: render.png)
POST inpaint_image
AI-fill a masked region of an image from a prompt (generative fill). Provide the source image URL and a mask URL where white marks the area to regenerate.
Param
Type
Description
image_url
string
required
Public URL of the source image
mask_url
string
required
Public URL of the mask image (white = region to fill)
prompt
string
optional
What to paint into the masked region
model
string
optional
Inpaint model (default: fal-ai/bria/genfill)
filename
string
optional
Output filename (default: retouched.png)
design_system_id
string
optional
Design system slug to scope storage to a client
POST retouch_image
Retouch an image by erasing/removing content within a masked region (object removal). Use mode "inpaint" to regenerate the region from a prompt instead.
Param
Type
Description
image_url
string
required
Public URL of the source image
mask_url
string
required
Public URL of the mask image (white = region to retouch)
mode
enum
optional
erase removes content (default); inpaint fills from the prompt
prompt
string
optional
Fill prompt (used when mode is "inpaint")
model
string
optional
Override model (default depends on mode)
filename
string
optional
Output filename (default: retouched.png)
design_system_id
string
optional
Design system slug to scope storage to a client
POST edit_image
Edit an image with a natural-language instruction (e.g. "remove the background", "make it night-time"). Some models (e.g. ideogram-rembg) need no prompt.
Param
Type
Description
image_url
string
required
Public URL of the source image
prompt
string
optional
Edit instruction (required for most models)
model
enum
optional
Edit model (see table below)
filename
string
optional
Output filename (default: edited.png)
design_system_id
string
optional
Design system slug to scope storage to a client
Available models
nano-banana-pro
Nano Banana Pro (default)
nano-banana-2
Nano Banana 2
nano-banana
Nano Banana
flux-kontext
Flux Kontext
qwen-edit
Qwen Edit
seedream-edit
Seedream Edit
ideogram-rembg
Ideogram background removal (no prompt needed)
POST enhance_image
Upscale / enhance an image's resolution and detail.
Param
Type
Description
image_url
string
required
Public URL of the source image
model
enum
optional
aura-sr (default), creative-upscaler, or clarity-upscaler
Crop an image by percentage from each edge. At least one crop value must be greater than 0.
Param
Type
Description
image_url
string
required
Public URL of the source image
crop_top
number
optional
Percent to crop from the top (0–100)
crop_bottom
number
optional
Percent to crop from the bottom (0–100)
crop_left
number
optional
Percent to crop from the left (0–100)
crop_right
number
optional
Percent to crop from the right (0–100)
filename
string
optional
Output filename (default: cropped.png)
design_system_id
string
optional
Design system slug to scope storage to a client
POST delete_generation
Delete a generated or uploaded image from storage by its Blob URL. Only image-gen/ and uploads/ URLs are deletable, and you must own the generation (or be an admin).
Param
Type
Description
url
string
required
The Blob URL of the image to delete
POST capture_url
Capture a screenshot of a public web page and return the PNG. Private/local hosts are blocked.
Param
Type
Description
url
string
required
Public http(s) URL to capture
width
number
optional
Viewport width in px (1–4096, default 1280)
height
number
optional
Viewport height in px (1–4096, default 720)
fullPage
boolean
optional
Capture the full scrollable page height (default false)
Design System Schema
The complete field reference for design systems. All fields are required for correct rendering.
Headline font stack (e.g. "Montserrat, sans-serif")
fontBody
string
Body font stack (e.g. "Inter, sans-serif")
fontImport
URL
Google Fonts import URL
customFonts
array
Uploaded fonts: [{name, url, fileName}]
fontH1 – fontH3
string
Per-element font overrides (blank = inherit)
fontCta
string
CTA button font (blank = inherit fontBody)
h1Weight – ctaWeight
string
CSS font-weight values
h1Transform – ctaTransform
string
none or uppercase
h1LetterSpacing – ctaLetterSpacing
string
CSS letter-spacing
ctaRadius
string
Button radius multiplier (e.g. 0.5)
ctaAlign
string
left or center
contentAlign
string
left or center
contentPosition
string
top, middle, or bottom
logoPosition
string
9-grid position (e.g. top-left, bottom-center)
logoScale
number
Logo size percentage (100 = default)
logoSvg
string
Logo SVG blob URL
logoFileName
string
Logo filename
disclaimer
string
Legal disclaimer text (blank if none)
disclaimerAlign
string
left or center
globalGenPrompt
string
Default AI image generation prompt prefix
globalLocks
object
Locked fields applied across all scenes
Project Schema
The full project object structure returned by get_project and expected by update_project.
{
"version": 2,
"designSystemId": "client-slug",
"preset": { /* full design system snapshot */ },
"activeFormat": "square",
"activeSceneId": "scene-uuid",
"totalDuration": 12,
"scenes": [ /* array of scene objects */ ]
}
Field
Type
Description
version
number
Schema version (always 2)
designSystemId
string
Linked design system slug
preset
object
Full design system embedded in project
activeFormat
enum
square, portrait, vertical, landscape, wide
activeSceneId
string
Currently selected scene
totalDuration
number
Sum of all scene durations
scenes
array
Ordered array of scene objects
Scene Schema
A scene may contain any of these fields. Almost all are optional — missing fields fall back to design-system and editor defaults, so a scene only needs the fields it actually sets.
Field
Type
Description
Content
id
string
Unique scene identifier
name
string
Scene display name
h1
string
Headline text
h2
string
Supporting text
h3
string
Third line
ctaText
string
CTA button label
disclaimerOverride
string
Per-scene disclaimer (blank = use preset)
duration
number
Scene duration in seconds
Layout
logoPosition
string
9-grid logo placement
logoScale
number
Per-scene logo scale (100 = default)
contentPosition
string
top, middle, bottom
contentAlign
string
left or center
ctaAlign
string
left or center
paddingPerFormat
object
Per-format padding: {square: {left, right}, ...}
layoutPerFormat
object
Per-format layout overrides (position/align/scale), inherited leftward across formats
Layout Template & Grid
layoutTemplate
string
Applied layout-template id — one of classic, centered, hero, topLead, bottomBar, footer, logoBottom, cornerMark, minimal, grid, cinematic (Centered logo), none, logoBottomLeft, logoBottomRight. Sets the slot fields above; a template is a starting point, not a constraint.
gridEnabled
boolean
Opt-in free-placement mode. When true, slot typography is suppressed and freeEls is rendered instead.
freeEls
array
Freely placed elements: [{id, role, text, cx, cy, w, h, angle, rotated}] — cx/cy/w/h are fractions of the frame (frame-fractional poses), so they hold across formats.
gridCols
number
Editor snap-lattice columns for placing/dragging grid elements
gridRows
number
Editor snap-lattice rows
gridPerFormat
object
Per-aspect-ratio grid: {square: {freeEls, gridCols, gridRows}, vertical: {...}} — swapped in/out on format switch (like bgPerFormat)
Vector text layers accept inline expression tokens wrapped in curly braces. Each token evaluates live against the scene clock, so a single text string can count a number, cycle through words, or print a stable random digit — with no keyframes. Tokens evaluate identically in preview and in server render, and a token persists across linked scenes (the linked clips share one timeline window, so a {0-100} ramps once across the whole chain rather than restarting at each cut).
Where to type them: Canvas mode → a Vector layer → the text field (placeholder Type text…). Any glyph/string entry in the layer's text stack accepts tokens. There is no MCP parameter — expressions live inside the text content itself.
Token
Type
What it does
{A-B}
Number
Tweens linearly from A to B over the layer's timeline window. {0-100} counts up; {100-3} counts down. A and B may be negative and/or decimal.
{w1, w2, …}
Words
Splits the window into N equal segments and shows each word in turn. {monkey, cat} = 50 / 50; the last word holds to the end. Whitespace around commas is trimmed.
{random}
Random
A single stable digit 0–9. It is seeded once (never flickers) and is identical in preview and every render chunk.
Number animation — decimals & direction
The decimal precision of the output matches the inputs: the result is shown to max(decimals of A, decimals of B) places. Both-integer inputs stay integer (rounded). Descending ranges (B < A) animate backwards.
You type
At 0%
At 50%
At 100%
Score: {0-100}
Score: 0
Score: 50
Score: 100
{100-3} left
100 left
52 left
3 left
{0-1.5}x
0.0x
0.8x
1.5x
{-20-20}°
-20°
0°
20°
Examples
Raised {0-100}% this quarter → counts 0 → 100 over the scene
Only {50-0} left! → counts down 50 → 0{Save big, Move fast, Win}→ three words, ~33% each, last holds
Gate {random}, Seat {random}→ two independent stable digits{0-100}% — {loading, almost, done}→ a counter and a word cycle in one line
Behaviour & gotchas
Multiple tokens
Every {…} in the string is evaluated. Each {random} gets its own stable digit (seeded by its position).
Plain text untouched
Anything outside braces is printed verbatim — $, %, punctuation, spaces all survive.
Unknown tokens
A brace group that matches none of the three forms (e.g. {hello}) is left as the literal text {hello} — no error, no blank.
Nested braces
Not supported. {{0-100}} won't tween; keep tokens flat.
Number vs words
A comma inside the braces makes it a word cycle; a single dash between two numbers makes it a tween. {0,1,2} is words; {0-2} is a number.
Start / end
Values clamp at the window edges — a number holds its first value before the window and its last value after it; a word cycle holds the final word.
Verified against app.html — the token runtime vexprEvalCore (parse + interpolation) and the live updater __vectorExprRuntime.
Animate & Guide Physics
Animate Physics turns a Vector layer's glyphs / SVGs into a particle system driven by force fields — no keyframing required. It lives in Canvas mode in the Animate Physics panel that appears when a vector layer is selected. An untouched panel is a no-op (all forces 0); dial in forces, or hit Randomize for a coherent recipe.
Modes
Goo (Organic)
A natural motion field — leaves in a breeze, a tornado, ripples, orbits. Forces act as continuous flow.
Inorganic (Geometry)
Points snap onto an angular, symmetrical form (grid, star, hexagon…) scaled to the canvas aspect so it stays proportionate at any size. Forces still animate them.
Force dials & layout
All forces default to 0 (the inert pose) and run 0–100. Forces and the global modulators can be keyframed across start / mid / end; layout values (Count, Fill, Fan Out) are structural — read once so particle identity stays locked across a linked chain.
Group
Controls
Range
Default
Nature forces
wind, turbulence, gravity, swirl, orbit, wave, float, spring
0–100
0
Layout
count (how many)
1–400
1
Layout
fill (cluster → edge-to-edge → overshoot)
0–500
60
Layout
fanOut
0–100
0
Global
speed
0–100
100
Global
intensity
0–200
100
Global
randomness
0–100
50
Global
stagger
0–100
20
Randomize & per-value locks
Randomize rolls a coherent natural recipe (leaves-in-breeze, tornado, planetary orbits, water ripple, rain) and re-rolls the seed. Per-value locks (the amber padlock on each slider) pin a value so Randomize leaves it untouched — useful for fixing Count or a single force while you reroll everything else. A value can be both keyframed (green) and locked (amber) at once.
Guide Physics prompt
The Guide Physics field (e.g. "form a ring · make particles rotate 360 · pulse") biases the running simulation toward a shape and/or motion. It calls the AI animate endpoint in guide mode and returns a { formation, modifier } spec — a formation settles particles into a shape, a modifier adds per-particle motion. Physics still runs underneath the guide, and clearing the prompt returns to pure physics. The guide is baked so preview matches export.
Form Sources flag-gated · beta
Form Sources let you supply the formation from your own asset instead of a text prompt — particles assemble into the shape. It is off by default; live customers see no change. Enable it without a deploy (sticky, then reload):
Sampled into dots — silhouette (filled) or edge (outline) via a blue-noise spread, deterministic per seed.
12–400 (160)
SVG
Drop an .svg
Points distributed along the combined path length (a path trace). Optional draw-on reveals the path as it plays.
12–400 (80)
Data
Paste numbers (e.g. 3, 7, 4, 9, 6)
Plotted as a chart polyline (x = index, larger values sit higher). Optional draw-on.
12–400 (64)
A→B morph across linked scenes: each member of a linked physics chain can hold its own formation, and particles melt from shape A in one scene to shape B in the next across the cut (count is locked across the chain so particle i maps consistently).
Other flag-gated creative features.Gradient FX (animated multi-stop / conic / mesh / WebGL-aurora gradients with a Randomize) is enabled the same way: ?gradientFx=on or localStorage.setItem('adflow_gradient_fx','on'). Both default OFF.
Verified against app.html — PHYSICS_DEFAULTS, the FORM_SOURCES / GRADIENT_FX flag blocks, and the Guide Physics + Randomize handlers.
Editor Feature Map
The editor's user-facing creative surface, beyond the API/MCP layer above. Most features are always visible; a few are flag-gated (enable via URL param or localStorage as shown above). This map reflects the shipping product — see the dedicated sections above for expressions and physics.
Credit balance, top-up now, auto-top-up (threshold + daily cap, min $5), card management via Stripe.
Live
Agent Skills
Skills are prompt modules your agent can invoke to get context-aware guidance for specific tasks. Install the adflow skill in your agent to unlock all MCP tools and workflow knowledge.
Core Skill
adflow
Primary skill for all Adflow operations. Covers MCP tool usage, design system creation, project workflows, scene field requirements, and AI image generation. Triggers on adflow, design system, create a project, build scenes, generate ad creative.
JSON Templates
Download these templates, fill in your client's brand details, and import via the API or MCP tools.
When MCP tools aren't available, use the REST API directly with your API key.
# List design systems
curl -s -H "X-API-Key: YOUR_KEY" "https://adflow.design/api/design-systems/list"
# Save / update design system
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/design-systems/save" \
-d '{"id": "client-slug", "data": { ... }}'
# List projects
curl -s -H "X-API-Key: YOUR_KEY" "https://adflow.design/api/projects/list"
# Get project by UUID
curl -s -H "X-API-Key: YOUR_KEY" "https://adflow.design/api/projects/PROJECT_UUID"
# Create new project# project blob MUST include version, designSystemId, preset.name, activeFormat
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/projects/save" \
-d '{"filename": "project-slug", "project": {"version":2, "designSystemId":"client-slug", "preset":{"name":"Client Name"}, "activeFormat":"square", "scenes":[...]}}'
# Update existing project
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/projects/save" \
-d '{"filename": "project-slug", "projectId": "UUID", "project": {"version":2, "designSystemId":"client-slug", "preset":{"name":"Client Name"}, "activeFormat":"square", "scenes":[...]}}'
# ─── AI generation (genai/*) — all POST, all return a blob URL ───# Generate an image from a text prompt# model: flux-dev (default), flux-pro, imagen4, imagen4-fast, gpt-image-1, nano-banana-pro, ideogram-v3, recraft-v3, recraft-v3-transparent
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/genai/generate" \
-d '{"model":"flux-dev", "prompt":"a red sports car at sunset", "width":2160, "height":2160, "filename":"car.png", "design_system_id":"client-slug"}'
# Edit an existing image with an instruction (the editing suite)# Same shape applies to /api/genai/inpaint, /retouch, and /enhance
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/genai/edit" \
-d '{"model":"nano-banana-pro", "prompt":"make the sky stormy", "image_url":"https://.../car.png", "filename":"car-edited.png"}'
# Outpaint / extend an image (fill new pixels around the frame)
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/genai/outpaint" \
-d '{"image_data":"data:image/png;base64,...", "expand_top":0, "expand_bottom":256, "expand_left":0, "expand_right":0, "prompt":"more road", "filename":"car-extended.png"}'
# Animate an element / scene into a video clip
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/genai/animate" \
-d '{"prompt":"slow pan across the car", "duration":6, "format":"mp4", "width":1080, "height":1080}'
# List your past generations
curl -s -H "X-API-Key: YOUR_KEY" "https://adflow.design/api/genai/list"
# ─── Renders (renders/*) ───# Rasterise composition HTML to a PNG screenshot (server-side Puppeteer)
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/renders/screenshot" \
-d '{"html":"<!doctype html>...", "width":1080, "height":1080}'
# Render composition HTML to a video on AWS Lambda (returns an executionArn)
curl -s -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
"https://adflow.design/api/renders/video" \
-d '{"html":"<!doctype html>...", "width":1080, "height":1080, "fps":30, "quality":"high", "format":"mp4"}'
# Poll render progress (executionArn returned by /renders/video)
curl -s -H "X-API-Key: YOUR_KEY" "https://adflow.design/api/renders/progress?executionArn=ARN"
Critical Rules
Font names must use SINGLE QUOTES.
Font values are injected into HTML style="" attributes. Double quotes break the attribute, silently dropping all CSS properties after the font declaration. Text renders at 16px with no styling.
All design system fields are required.
Missing fields cause the renderer to fall back to DEFAULT_PRESET values (system font, black text, white background). Always provide the complete field set.
Scenes inherit from the design system.
The create_project tool automatically inherits textColor, ctaBgColor, ctaTextColor, contentAlign, contentPosition, and logoPosition from the design system. You can override any field per-scene in the create_project call or via update_project afterwards.
Font sizes are read-only.
Font sizes are calculated by the renderer from format dimensions. Do not attempt to set font sizes in design systems or scenes.
Projects MUST include designSystemId in the project blob.
The /api/projects/save endpoint reads project.designSystemId to populate the design_system_id DB column. Projects are filtered by design system in the UI — if this field is missing or null, the project will not appear in the project list. You must also include version: 2, preset: {name: "..."}, and activeFormat for the project to load correctly.
Autosave can overwrite API updates.
The frontend autosaves to the server every 2 seconds. If a user has the project open while your agent updates via API, the frontend's next autosave will overwrite your changes. Coordinate with the user to close the project before making API updates.
Adflow — AI-native ad creative builder — adflow.design