Overview

The ZOOOP REST API lets you generate images, video, and audio programmatically — the same models available in the ZOOOP web app, driven from your own code.

Base URL — every endpoint lives under https://zooop.ai/api/public/v1. The version (v1) is fixed in the path.

How it works — generation is asynchronous. You submit a task, then poll it until it reaches a terminal state:

  1. POST /tasks — submit a generation request and get back a taskId.
  2. GET /tasks/{id} — poll until status is succeeded, failed, or cancelled.
  3. Read the result from outputs[].url.

All responses are JSON. Authentication uses a Bearer API key — see Authentication.

Authentication

Every request must include your API key as a Bearer token:

Authorization: Bearer zpk_live_xxxxxxxx...

A key is shown in full only once, at creation — store it somewhere safe.

Personal vs. team keys are created in different places:

  • Personal keys bill against your personal credit balance. Create them on the API Keys page (user settings → API Keys).
  • Team keys bill against the team’s shared balance. They are created separately, inside the team admin panel — open Your teams, pick a team, and go to its API Keys tab. (Requires owner/admin role.)

Key properties — each key is bound to a project and can carry an optional expiry and a daily credit cap. Call GET /me to inspect a key’s remaining quota and rate limits.

Requests without a valid key return 401. A banned account, or a key whose project was deleted, returns 403.

curl https://zooop.ai/api/public/v1/me \
-H "Authorization: Bearer $ZOOOP_API_KEY"

Quickstart

Submit an image generation task and wait for the result.

  1. Get an API key and export it as ZOOOP_API_KEY — a personal key, or a team key from your team admin panel (see Authentication).
  2. Pick a model — call GET /api/public/v1/models to discover interfaceId / versionId pairs, or pass an aiTool slug instead.
  3. Submit the task, then poll until it finishes and read outputs[0].url.

The snippet on the right runs the full submit → poll → read-result loop.

# 1. Submit a task
curl -X POST https://zooop.ai/api/public/v1/tasks \
-H "Authorization: Bearer $ZOOOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"interfaceId": "your-model-interface-id",
"versionId": "your-model-version-id",
"params": { "prompt": "a cinematic shot of a city at night" }
}'
# -> { "taskId": "abc123", "status": "queued", ... }
# 2. Poll until status is succeeded / failed / cancelled
curl https://zooop.ai/api/public/v1/tasks/abc123 \
-H "Authorization: Bearer $ZOOOP_API_KEY"

Errors & rate limits

All errors share the same JSON shape: an error object with message, type, and a stable machine-readable code (plus an optional param and extra fields).

type is one of authentication_error, permission_error, invalid_request_error, rate_limit_error, api_error.

Common codes

HTTPcodeMeaning
401missing_token / invalid_tokenMissing or invalid key
403account_banned / token_project_unboundAccount or key unusable
400invalid_payload / unknown_modelMalformed request
402token_daily_cap_reachedKey’s daily credit cap hit
429rate_limitedToo many requests — see Retry-After

Rate limits — applied per key, per 60-second window. Exceeding a limit returns 429 with a Retry-After header.

EndpointLimit
POST /tasks, GET /tasks/{id}60 / min
POST /uploads30 / min
GET /uploads/{id}, GET /me, POST /quote, GET /ai-tools120 / min
POST /describe-image10 / min
GET /modelsno fixed limit
POST

Create a task

https://zooop.ai/api/public/v1/tasks

Submit a generation request. Returns a queued task you can poll.

Authorization required. Rate limit: 60 requests/min per key.

Idempotency — pass an Idempotency-Key header (1–256 chars). Repeats within 24 hours return the original task instead of creating a new one.

Errors: 400 invalid_payload / invalid_idempotency_key / unknown_model, 403 model_not_public, 404 unknown_ai_tool, 402 token_daily_cap_reached, 429 rate_limited.

Parameters

interfaceIdRequired
string
Model interface to run. Required with `versionId`. Mutually exclusive with `aiTool`.
versionIdRequired
string
Interface version to run. Required when `interfaceId` is provided.
aiTool
string
An AI-tool slug to run instead of a raw model. Mutually exclusive with `interfaceId` / `versionId`.
paramsRequired
object
Generation parameters for the chosen model. Up to 50 keys.
prompt
string
Text prompt. Up to 10,000 characters.
[other params]
string | number | boolean | array
Model-specific params (discover them via `GET /models`). String values up to 2,000 chars; arrays up to 20 items. Media URLs must be hosted on zooop.ai — upload them via `POST /uploads` first.

Response

taskId
string
The created task id. Use it with `GET /tasks/{id}`.
status
string
Always `queued` on creation.
modelId
string
The resolved interface id.
versionId
string
The resolved version id.
idempotent
boolean
Present and `true` only when an idempotent retry matched an existing task.
Example response
{
"taskId": "a1b2c3d4-0000-0000-0000-000000000000",
"status": "queued",
"modelId": "img-interface-id",
"versionId": "v1-version-id"
}
curl -X POST https://zooop.ai/api/public/v1/tasks \
-H "Authorization: Bearer $ZOOOP_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-unique-key-123" \
-d '{
"interfaceId": "your-model-interface-id",
"versionId": "your-model-version-id",
"params": { "prompt": "a cinematic shot of a city at night" }
}'
GET

Get a task

https://zooop.ai/api/public/v1/tasks/{id}

Fetch a task by id. Poll this until status is terminal.

Authorization required. Rate limit: 60 requests/min per key.

Scope — a key can only read its own tasks. Requesting another key’s task id returns 404 unknown_task.

Parameters

idRequired
string
Path parameter — the task id returned by Create a task.

Response

taskId
string
The task id.
status
string
One of `queued`, `running`, `succeeded`, `failed`, `cancelled`. Poll until it is one of the last three (terminal).
outputs
object[]
Result assets (currently at most one).
url
string
Full URL of the generated asset.
thumbnailUrl
string
Optional thumbnail URL.
error
object | null
Present only when `status` is `failed`.
message
string
Human-readable failure reason.
code
string
Machine-readable failure code.
creditsCharged
number
Credits actually charged once billing settles.
createdAt
string
ISO 8601 creation timestamp.
completedAt
string | null
ISO 8601 timestamp, set when the task reaches a terminal state.
Example response
{
"taskId": "a1b2c3d4-0000-0000-0000-000000000000",
"status": "succeeded",
"outputs": [
{
"url": "https://zooop.ai/cdn/.../result.png",
"thumbnailUrl": "https://zooop.ai/cdn/.../thumb.png"
}
],
"error": null,
"creditsCharged": 12,
"createdAt": "2026-06-22T10:00:00.000Z",
"completedAt": "2026-06-22T10:00:45.000Z"
}
curl https://zooop.ai/api/public/v1/tasks/TASK_ID \
-H "Authorization: Bearer $ZOOOP_API_KEY"
POST

Upload a file

https://zooop.ai/api/public/v1/uploads

Upload media to get a zooop.ai URL you can pass into task params.

Authorization required. Rate limit: 30 requests/min per key.

Images are moderated synchronously; videos are moderated asynchronously (poll the upload). Errors: 400 invalid_payload, 413 file_too_large, 451 moderation_blocked, 429 rate_limited, 502 storage_upload_failed.

Parameters

Content-TypeRequired
header
The file’s MIME type. Allowed: image/png, image/jpeg, image/webp, image/gif, audio/mpeg, audio/wav, audio/ogg, audio/webm, video/mp4, video/webm, video/quicktime.
bodyRequired
binary
The raw file bytes (NOT multipart/form-data). Max 100 MB. Set `Content-Length`.

Response

status
string
`ready` for images/audio (synchronous), or `processing` for video (returns 202).
url
string
CDN URL of the uploaded file. Pass this into task `params`. (ready only)
size
number
Byte size (ready only).
contentType
string
Echoed MIME type (ready only).
uploadId
string
Poll id for async video uploads (processing only).
pollUrl
string
Path to poll for async video uploads (processing only).
Example response
// image / audio — 200 OK
{
"status": "ready",
"url": "https://cdn.zooop.ai/.../file.png",
"size": 482113,
"contentType": "image/png"
}
// video — 202 Accepted (poll for moderation)
{
"status": "processing",
"uploadId": "b2c3d4e5-...",
"pollUrl": "/api/public/v1/uploads/b2c3d4e5-..."
}
# Send raw bytes; Content-Type must match the file
curl -X POST https://zooop.ai/api/public/v1/uploads \
-H "Authorization: Bearer $ZOOOP_API_KEY" \
-H "Content-Type: image/png" \
--data-binary @./input.png
GET

Get an upload

https://zooop.ai/api/public/v1/uploads/{uploadId}

Poll an async (video) upload until moderation finishes.

Authorization required. Rate limit: 120 requests/min per key. Scoped to your key (others’ uploads return 404 unknown_upload).

Parameters

uploadIdRequired
string
Path parameter — the `uploadId` from a processing upload.

Response

status
string
One of `processing` (202), `ready`, `blocked`, `errored`.
url
string
CDN URL (ready only).
contentType
string
MIME type (ready only).
labels
string
Comma-separated moderation labels (blocked only).
reason
string
Failure reason (errored only).
Example response
// ready — 200 OK
{
"status": "ready",
"url": "https://cdn.zooop.ai/.../clip.mp4",
"contentType": "video/mp4"
}
curl https://zooop.ai/api/public/v1/uploads/UPLOAD_ID \
-H "Authorization: Bearer $ZOOOP_API_KEY"
GET

List models

https://zooop.ai/api/public/v1/models

Discover models and their interfaceId / versionId pairs and params.

Authorization required. Both type and subtype are required query params.

Parameters

typeRequired
query string
Media category, e.g. `image`, `video`, `audio`.
subtypeRequired
query string
Sub-category, e.g. `text-to-image`. Invalid pairs return `400` with a `validCategories` list.

Response

models
object[]
Available models for the category.
id
string
interfaceId — pass to `POST /tasks`.
name
string
Display name.
promptRequired
boolean
Whether a prompt is required.
params
object[]
Param definitions: id, type, displayName, required, default, constraints, options.
versions
object[]
Versions, each with id (versionId), name, and `typicalPrice` { typicalCredits, unit, note }.
Example response
{
"models": [
{
"id": "interface-uuid",
"name": "Seedream 5.0 Lite",
"type": "image",
"subType": "text-to-image",
"promptRequired": true,
"params": [ { "id": "aspect_ratio", "type": "enum", "options": ["1:1", "16:9"] } ],
"versions": [
{ "id": "version-uuid", "name": "v1", "typicalPrice": { "typicalCredits": 4, "unit": "image" } }
]
}
]
}
curl "https://zooop.ai/api/public/v1/models?type=image&subtype=text-to-image" \
-H "Authorization: Bearer $ZOOOP_API_KEY"
GET

List AI tools

https://zooop.ai/api/public/v1/ai-tools

AI tools are ready-made presets (upscale, remove-bg, …) run by slug.

Authorization required. Rate limit: 120 requests/min per key. Errors: 400 invalid_type.

Parameters

type
query string
Optional filter — `image` or `video`. Omit for all.

Response

aiTools
object[]
Available AI tools.
slug
string
Stable slug — pass as `aiTool` to `POST /tasks` or `POST /quote`.
name
string
Display name.
mediaType
string
`image` or `video`.
summary
string
One-line description.
params
object[]
Param definitions (same shape as models).
typicalPrice
object | null
{ typicalCredits, unit, note }.
Example response
{
"aiTools": [
{
"slug": "background-removal",
"name": "Background Removal",
"mediaType": "image",
"summary": "Remove the background from an image.",
"params": [ { "id": "image_url", "type": "image", "required": true } ],
"typicalPrice": { "typicalCredits": 2, "unit": "image" }
}
]
}
curl "https://zooop.ai/api/public/v1/ai-tools?type=image" \
-H "Authorization: Bearer $ZOOOP_API_KEY"
GET

Get an AI tool

https://zooop.ai/api/public/v1/ai-tools/{slug}

Fetch a single AI tool by slug, including its params.

Authorization required. Rate limit: 120 requests/min per key. Errors: 404 unknown_ai_tool.

Parameters

slugRequired
string
Path parameter — the tool’s slug.

Response

slug
string
Stable slug.
name
string
Display name.
mediaType
string
`image` or `video`.
summary
string
One-line description.
params
object[]
Param definitions.
typicalPrice
object | null
{ typicalCredits, unit, note }.
Example response
{
"slug": "background-removal",
"name": "Background Removal",
"mediaType": "image",
"summary": "Remove the background from an image.",
"params": [ { "id": "image_url", "type": "image", "required": true } ],
"typicalPrice": { "typicalCredits": 2, "unit": "image" }
}
curl https://zooop.ai/api/public/v1/ai-tools/background-removal \
-H "Authorization: Bearer $ZOOOP_API_KEY"
POST

Quote a task

https://zooop.ai/api/public/v1/quote

Estimate the credit cost of a task before submitting. Never charges.

Authorization required. Rate limit: 120 requests/min per key. Errors: 400 invalid_payload, 404 unknown_model / unknown_ai_tool, 403 model_not_public.

Parameters

interfaceId
string
With `versionId` — the model to price. Mutually exclusive with `aiTool`.
versionId
string
Required with `interfaceId`.
aiTool
string
An AI-tool slug. Mutually exclusive with `interfaceId`.
params
object
Same params as `POST /tasks`.

Response

credits
number
Estimated credit cost.
estimatedSeconds
number | null
Best-effort ETA; null for new models with no history.
modelId
string
Resolved interface id.
versionId
string
Resolved version id.
modelName
string
Resolved model name.
Example response
{
"credits": 12,
"estimatedSeconds": 45,
"modelId": "interface-uuid",
"versionId": "version-uuid",
"modelName": "Seedance 2.0"
}
curl -X POST https://zooop.ai/api/public/v1/quote \
-H "Authorization: Bearer $ZOOOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "interfaceId": "...", "versionId": "...", "params": { "prompt": "..." } }'
POST

Describe an image

https://zooop.ai/api/public/v1/describe-image

Analyze a reference image into a ready-to-use prompt. Costs 1 credit.

Authorization required. Rate limit: 10 requests/min per key (vision is expensive). Charges 1 credit up front, refunded on failure.

Errors: 400 invalid_payload, 402 insufficient_credits, 429 token_daily_cap_reached / rate_limited, 422 policy_violation, 503 vision_unavailable.

Parameters

imageUrlRequired
string
A zooop.ai CDN image URL (from `POST /uploads`). External URLs are rejected.
language
string
Optional output language (e.g. `en`, `zh`, `ja`). Defaults to English.

Response

overallDescription
string
The canonical, ready-to-use description (always non-empty).
subject
string
Best-effort dimension fields: subject, composition, style, lighting, palette, mood.
camera
string | null
Camera notes, may be null.
credits
number
Always 1.
Example response
{
"credits": 1,
"overallDescription": "A neon-lit alley at night, rain-slicked...",
"subject": "a lone figure under an umbrella",
"composition": "centered, low angle",
"style": "cinematic, cyberpunk",
"lighting": "neon, high contrast",
"palette": "magenta and teal",
"mood": "moody",
"camera": "35mm, shallow depth of field"
}
curl -X POST https://zooop.ai/api/public/v1/describe-image \
-H "Authorization: Bearer $ZOOOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "imageUrl": "https://cdn.zooop.ai/.../ref.png", "language": "en" }'
GET

Inspect your key

https://zooop.ai/api/public/v1/me

Introspect the calling key: quota, limits, project, and balance.

Authorization required. Rate limit: 120 requests/min per key. Team keys return team instead of user (the creator’s personal balance is never exposed).

Response

key
object
The calling key.
id
string
Key id.
prefix
string
Display prefix, e.g. `zpk_live_AbCdEfGh`.
label
string
Your label for the key.
expiresAt
string | null
ISO 8601 expiry, or null.
dailyCreditCap
number | null
Daily credit cap, or null for unlimited.
creditsSpentToday
number
Credits this key spent today.
creditsRemainingToday
number | null
cap − spent, or null if no cap.
project
object
The bound project { id, name }.
user
object
{ creditBalance } — personal keys only.
team
object
{ id, creditBalance } — team keys only.
limits
object
Current rate limits { tasksPerMin, uploadsPerMin, uploadPollPerMin }.
Example response
{
"key": {
"id": "token-uuid",
"prefix": "zpk_live_AbCdEfGh",
"label": "Production",
"expiresAt": null,
"dailyCreditCap": 1000,
"creditsSpentToday": 120,
"creditsRemainingToday": 880
},
"project": { "id": "project-uuid", "name": "My Project" },
"user": { "creditBalance": 5000 },
"limits": { "tasksPerMin": 60, "uploadsPerMin": 30, "uploadPollPerMin": 120 }
}
curl https://zooop.ai/api/public/v1/me \
-H "Authorization: Bearer $ZOOOP_API_KEY"