The task object
Every field of a task, the result shape for each task type, and what the create, list, status, and result endpoints return.
Every generation and analysis call creates a task, and every task endpoint returns some part of this object. The lifecycle, billing, and file lifetimes are on tasks.
Where each part comes from#
| Call | Returns |
|---|---|
A POST that creates a task | taskId, estimatedCost, sometimes access. See create response |
GET /tasks | A page of rows: id, type, status, cost, timestamps |
GET /tasks/{id} | The full object |
GET /tasks/{id}/status | status only |
GET /tasks/{id}/result | id, type, status, result |
| A webhook delivery | task.id, request, and result or errors. See webhook payloads |
Poll /status, then read /result. Both are served from a cache and accept a
pat_ token.
GET /tasks/{id} reads the database and needs an API key.
The object#
{
"data": {
"id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"type": "image.generate",
"status": "completed",
"request": {
"model": "black-forest-labs/flux.2-pro",
"prompt": "A lighthouse at dusk, film grain",
"count": 1,
"metadata": { "orderId": "ord_42" }
},
"result": {
"model": "black-forest-labs/flux.2-pro",
"images": [
{
"status": "success",
"id": "img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk",
"url": "https://cdn.mynth.io/images/img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk.webp",
"mynth_url": "https://cdn.mynth.io/images/img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk.webp",
"size": "1536x1024",
"format": "webp"
}
]
},
"errors": null,
"cost": "0.03000000",
"userId": "user_01JD8G3W1R5T6Y7U8I9O0P1Q2W",
"apiKeyId": "ak_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"createdAt": "2026-07-04T10:00:00.000Z",
"updatedAt": "2026-07-04T10:00:12.000Z"
}
}| Field | Type | Notes |
|---|---|---|
id | string | tsk_ + a ULID. Sorts by creation time |
type | string | One of the six task types. Decides the shape of request and result |
status | pending | completed | failed | pending covers queued and running. A settled task never changes again |
request | object | The body as accepted, with defaults filled in. See request |
result | object | null | Set only when completed. Shape depends on type |
errors | [{ code, message? }] | null | Set only when failed |
cost | decimal string | null | USD charged, 8 decimal places. Set only when completed |
userId | string | The account that owns the task |
apiKeyId | string | null | The key that created it. null for dashboard and playground tasks |
createdAt | ISO 8601 string | UTC |
updatedAt | ISO 8601 string | UTC. The last change |
The combinations are fixed:
status | result | errors | cost |
|---|---|---|---|
pending | null | null | null |
completed | set | null | set |
failed | null | at least one entry | null |
A completed generation can still hold failed items. Check each entry in
result.images or result.videos. Errors
lists the codes.
Money is always a decimal string: cost, estimatedCost, and a video's own
cost. Add amounts up with a decimal type, not floats.
Request#
request echoes the body after validation:
- Defaults are filled in, such as
model: "auto"andcount: 1onimage.generate, oreffort: "high"onimage.review. - Fields the schema does not know are gone. If a setting seems ignored, look here.
metadatacomes back unchanged, here and in every webhook. Put your own ids in it to match a task to your records.- URLs in
webhook.customare shortened to the scheme, host, and first 12 characters of the path, because they often carry a token.
Each endpoint page under Endpoints lists the fields its task type accepts.
Task types#
type | Created by | result holds |
|---|---|---|
image.generate | POST /image/generate | model, images[], magic_prompt? |
image.remove_background | POST /image/remove-background | image |
image.rate | POST /image/rate | level |
image.alt | POST /image/alt | alt |
image.review | POST /image/review | score, summary, findings, strengths |
video.generate | POST /video/generate | model, videos[] |
Fields marked ? are absent, not null, when they do not apply.
image.generate#
{
"model": "black-forest-labs/flux.2-pro",
"images": [
{
"status": "success",
"id": "img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk",
"url": "https://assets.example.com/renders/img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk.webp",
"mynth_url": "https://cdn.mynth.io/images/img_V1StGXR8Z5jdHi6BmyT0sC1pQ2rN4wLk.webp",
"size": "1536x1024",
"format": "webp",
"rating": { "status": "success", "level": "sfw" }
},
{
"status": "failed",
"error": {
"code": "RESTRICTED_CONTENT",
"message": "The request was blocked by content moderation."
}
}
],
"magic_prompt": { "positive": "A lone lighthouse on a rocky shore at dusk, ..." }
}| Field | Type | Notes |
|---|---|---|
model | string | The model that ran. With auto, the one Mynth picked |
images | array | One entry per requested image, each success or failed |
magic_prompt? | { positive, negative? } | The rewritten prompt, when the request set magic_prompt: true |
A successful image:
| Field | Type | Notes |
|---|---|---|
status | "success" | |
id | string | img_ + 32 random characters |
url | string | null | Your storage when a destination was named, else the same as mynth_url. null if that upload failed |
mynth_url | string | Mynth's copy. Always set, served for 7 days |
size | string | Measured from the file, {width}x{height} |
format | png | jpg | webp | What output.format asked for, or what the provider returned |
rating? | object | When the request set rating: { status: "success", level } or { status: "failed", error: { code } } |
A failed image is { "status": "failed", "error": { "code", "message?" } }
with nothing else, and is not charged. Generated images carry no
destination block, so a failed upload shows only as url: null.
image.remove_background#
{
"image": {
"id": "img_Q8mZr2LkT0vWc5NhY7pD3xFa9GsJ1bEu",
"url": "https://cdn.mynth.io/images/img_Q8mZr2LkT0vWc5NhY7pD3xFa9GsJ1bEu.png",
"mynth_url": "https://cdn.mynth.io/images/img_Q8mZr2LkT0vWc5NhY7pD3xFa9GsJ1bEu.png",
"size": "1024x1024",
"format": "png"
}
}image has the fields of a successful image.generate entry, without
status and rating. format is png or webp. There is no per-item
failure: if the work fails, the task is failed.
When the request named a destination, image also carries destination:
{ status: "success", name }, or
{ status: "failed", name, error: { code, message?, provider_response? } }
next to url: null.
image.rate#
{ "level": "sfw" }level is sfw or nsfw by default, or one of your value strings with
custom levels.
image.alt#
{ "alt": "A white lighthouse on dark rocks, lit by an orange sunset sky" }alt is 1 to 160 characters.
image.review#
{
"score": 3,
"summary": "Clean composition with one visible defect in the left hand.",
"findings": [
{
"finding": "The left hand has six fingers",
"category": "anatomy",
"severity": "major",
"where": "Bottom left, the hand resting on the railing",
"confidence": "high"
}
],
"strengths": [{ "strength": "Warm, consistent lighting", "confidence": "medium" }]
}| Field | Type | Notes |
|---|---|---|
score | number, 1 to 4 | Median of the reviewers' scores. Higher is better |
summary | string | A short prose summary |
findings[].category | string | Usually anatomy, text, composition, artifact, color, or lighting. An open set |
findings[].severity | critical | major | minor | |
findings[].confidence | low | medium | high | Reviewer agreement: bare threshold, majority, strong consensus |
strengths[] | { strength, confidence } | Same confidence scale |
video.generate#
{
"model": "bytedance/seedance-2.0-mini",
"videos": [
{
"status": "success",
"id": "vid_3HkP9wQz7LmR2tXc8VbN5dFy0JsA4gUe",
"url": "https://cdn.mynth.io/videos/vid_3HkP9wQz7LmR2tXc8VbN5dFy0JsA4gUe.mp4",
"mynth_url": "https://cdn.mynth.io/videos/vid_3HkP9wQz7LmR2tXc8VbN5dFy0JsA4gUe.mp4",
"cost": "0.40500000",
"duration": 5,
"resolution": "720p",
"audio": true
}
]
}| Field | Type | Notes |
|---|---|---|
id | string | vid_ + 32 random characters |
url | string | Never null. Video has no destinations |
mynth_url | string | The same as url today |
cost | decimal string | What this video cost |
duration | number | Seconds |
resolution | 480p | 720p | 1080p | 4k | |
audio | boolean | Whether the video has generated audio |
A failed video is { "status": "failed", "error": { "code", "message?" } },
like a failed image.
Create response#
Every POST that creates a task answers 201:
{
"data": {
"taskId": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"estimatedCost": "0.03",
"access": { "publicAccessToken": "pat_eyJhbGciOiJIUzI1NiJ9..." }
}
}| Field | Notes |
|---|---|
taskId | Pass it to every task endpoint |
estimatedCost | USD held on your balance until the task settles. The final cost is normally equal or lower |
access.publicAccessToken? | Image generate, remove background, and video generate only. Rules |
The media is never in this response. Wait for the task with polling or a webhook.
Listing tasks#
GET /tasks returns the calling key's tasks, newest first. Rows omit
request and result, so fetch a task by id for those.
| Query | Default | Notes |
|---|---|---|
limit | 20 | 1 to 100 |
after | none | A task id. Returns tasks older than it |
{
"data": [
{
"id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"type": "image.generate",
"status": "completed",
"cost": "0.03000000",
"createdAt": "2026-07-04T10:00:00.000Z",
"updatedAt": "2026-07-04T10:00:12.000Z"
}
]
}There is no hasMore and no total. To page, pass the last id you received
as after. A page shorter than limit is the last one.
let after: string | undefined;
do {
const url = new URL("https://api.mynth.io/tasks");
url.searchParams.set("limit", "100");
if (after) url.searchParams.set("after", after);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.MYNTH_API_KEY}` },
});
const { data } = await res.json();
for (const task of data) console.log(task.id, task.status, task.cost);
after = data.length === 100 ? data.at(-1).id : undefined;
} while (after);After a create request times out, look here before resending. If the task is listed, it was created, and sending the request again would create and charge a second one.
Status and result#
{ "data": { "status": "pending" } }{
"data": {
"id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"type": "image.alt",
"status": "completed",
"result": { "alt": "A white lighthouse on dark rocks, lit by an orange sunset sky" }
}
}/result answers 200 while the task is pending, with result: null. It
never includes errors, so for a failed task read GET /tasks/{id}.
Next steps#
- Tasks: statuses, billing, retries, and file lifetimes.
- Webhook payloads: the same result, pushed to you.
- Errors: the codes in
errorsand on failed items.