• Docs
  • API reference
  • SDKs & tools
  • Models
  • Changelog
Sign inGet an API key
DocsAPI referenceSDKs & toolsModelsChangelog

Basics

IntroductionAuthenticationThe task objectWebhook payloadsErrors

Endpoints

POSTGenerate imagePOSTEstimate costPOSTUpload imagesPOSTGenerate alt textPOSTReview imagePOSTRate imagePOSTRemove backgroundPOSTUpscale image
GETList tasksGETGet taskGETGet task statusGETGet task result
  1. API reference
  2. /
  3. Basics

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.

PreviousAuthenticationNextWebhook payloads

On this page

Where each part comes fromThe objectRequestTask typesimage.generateimage.remove_backgroundimage.upscaleimage.rateimage.altimage.reviewvideo.generateCreate responseListing tasksStatus and resultNext steps

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

CallReturns
A POST that creates a tasktask_id, estimated_cost, sometimes public_access_token. See create response
GET /tasksA page of rows: id, type, status, cost, timestamps
GET /tasks/{id}The full object
GET /tasks/{id}/statusstatus only
GET /tasks/{id}/resultid, type, status, result
A webhook deliveryThe full object, as the event's data. 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": { "order_id": "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",
    "user_id": "user_01JD8G3W1R5T6Y7U8I9O0P1Q2W",
    "api_key_id": "ak_01KE7XWWEQ4MCGWKBQKJ1G47RP",
    "created_at": "2026-07-04T10:00:00.000Z",
    "updated_at": "2026-07-04T10:00:12.000Z"
  }
}
FieldTypeNotes
idstringtsk_ + a ULID. Sorts by creation time
typestringOne of the seven task types. Decides the shape of request and result
statuspending | completed | failedpending covers queued and running. A settled task never changes again
requestobjectThe body as accepted, with defaults filled in. See request
resultobject | nullSet only when completed. Shape depends on type
errors[{ code, message? }] | nullSet only when failed
costdecimal string | nullUSD charged, 8 decimal places. Set only when completed
user_idstringThe account that owns the task
api_key_idstring | nullThe key that created it. null for dashboard and playground tasks
created_atISO 8601 stringUTC
updated_atISO 8601 stringUTC. The last change

The combinations are fixed:

statusresulterrorscost
pendingnullnullnull
completedsetnullset
failednullat least one entrynull

completed means the task finished and has a result. It does not mean every item succeeded: a generation can complete with failed images or videos, so check each entry's status in result.images or result.videos. failed means the task as a whole failed: there is no result, nothing is charged, and errors says why. Errors lists the codes.

Money is always a decimal string: cost, estimated_cost, 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" and count: 1 on image.generate, or effort: "high" on image.review.
  • Field names are snake_case, the same as you send them. A body with a field the endpoint does not define is rejected, so nothing is dropped.
  • metadata comes back unchanged, here and in every webhook. Put your own ids in it to match a task to your records.
  • URLs in webhook.custom are cut down to scheme://host, because they often carry a token.

Each endpoint page under Endpoints lists the fields its task type accepts.

Task types

typeCreated byresult holds
image.generatePOST /image/generatemodel, images[], magic_prompt?
image.remove_backgroundPOST /image/remove-backgroundimage
image.upscalePOST /image/upscaleimage
image.ratePOST /image/ratelevel
image.altPOST /image/altalt
image.reviewPOST /image/reviewscore, summary, findings, strengths
video.generatePOST /video/generatemodel, 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, ..." }
}
FieldTypeNotes
modelstringThe model that ran. With auto, the one Mynth picked
imagesarrayOne 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:

FieldTypeNotes
status"success"
idstringimg_ + 32 random characters
urlstring | nullYour storage when a destination was named, else the same as mynth_url. null if that upload failed
mynth_urlstringMynth's copy. Always set, served for 7 days
sizestringMeasured from the file, {width}x{height}
formatpng | jpg | webpWhat output.format asked for, or what the provider returned
rating?objectWhen 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.upscale

{
  "image": {
    "id": "img_Hn4cW8pLx2RsT6vYb0QjM9kE3dAf7ZuG",
    "url": "https://cdn.mynth.io/images/img_Hn4cW8pLx2RsT6vYb0QjM9kE3dAf7ZuG.png",
    "mynth_url": "https://cdn.mynth.io/images/img_Hn4cW8pLx2RsT6vYb0QjM9kE3dAf7ZuG.png",
    "size": "3072x4608",
    "format": "png"
  }
}

Same shape as image.remove_background, with destination under the same rules. format is png, jpg, or webp. size is what the provider returned, which can differ slightly from the source times the factor.

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" }]
}
FieldTypeNotes
scorenumber, 1 to 4Median of the reviewers' scores. Higher is better
summarystringA short prose summary
findings[].categorystringUsually anatomy, text, composition, artifact, color, or lighting. An open set
findings[].severitycritical | major | minor
findings[].confidencelow | medium | highReviewer 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",
      "aspect_ratio": "9:16",
      "audio": true
    }
  ]
}
FieldTypeNotes
idstringvid_ + 32 random characters
urlstring | nullThe same as mynth_url today. Nullable, as on images, so video destinations can be added without a breaking change. Write url ?? mynth_url
mynth_urlstringMynth's copy. Always set
costdecimal stringWhat this video cost
durationnumberSeconds
resolution480p | 720p | 1080p | 4k
aspect_ratiostring | nullThe ratio it was rendered at, such as 9:16. null when a first frame set the shape
audiobooleanWhether 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": {
    "task_id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
    "estimated_cost": "0.03",
    "public_access_token": "pat_eyJhbGciOiJIUzI1NiJ9..."
  }
}
FieldNotes
task_idPass it to every task endpoint
estimated_costUSD held on your balance until the task settles. The final cost is normally equal or lower
public_access_token?Only when the request set generate_public_access_token: true, on image generate, remove background, upscale, and video generate. 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.

QueryDefaultNotes
limit201 to 100
afternoneA task id. Returns tasks older than it
{
  "data": [
    {
      "id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
      "type": "image.generate",
      "status": "completed",
      "cost": "0.03000000",
      "created_at": "2026-07-04T10:00:00.000Z",
      "updated_at": "2026-07-04T10:00:12.000Z"
    }
  ]
}

There is no has_more 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 errors and on failed items.