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

TypeScript SDK

OverviewInstallationClientGenerating mediaTasks and pollingErrors

CLI

OverviewLogging inCommands

Integrations

ConvexTanStack Start

Agents

llms.txtSkillsAgent prompt
  1. SDKs & tools
  2. /
  3. TypeScript SDK

Tasks and polling

Wait with generate(), return early with generateAsync(), how long the SDK polls, and how to hand a browser the pat_ token.

PreviousGenerating mediaNextErrors

On this page

TaskAsyncHow long it pollsPoll from the browserPartial resultsNext steps

Every SDK call that does work creates a task. generate() polls that task for you. generateAsync() returns a TaskAsync right after the task is created, and you decide who waits.

import Mynth from "@mynthio/sdk";

const mynth = new Mynth();

const pending = await mynth.image.generateAsync({
  model: "black-forest-labs/flux.2-pro",
  prompt: "A lighthouse at dusk, film grain",
});

console.log(pending.id); // tsk_...
const task = await pending.wait();
console.log(task.urls[0]);

image.generate() is generateAsync() followed by wait(). The tools follow the same pattern: rate() and rateAsync(), alt() and altAsync(), review() and reviewAsync(), removeBackground() and removeBackgroundAsync(), upscale() and upscaleAsync(), video.generate() and video.generateAsync(). upload() and video.estimate() do not create tasks.

TaskAsync

MemberHolds
idThe task id
access{ publicAccessToken? }, the browser token when the request asked for one
wait()Polls until the task settles, then returns a plain result object

wait() polls until completed, then loads the full task and builds the result. Calling it twice returns the same promise. A task that settles as failed makes it throw TaskAsyncTaskFailedError. Errors lists every throw.

How long it polls

WaitIntervalGives up after
Images and toolsevery 2.5 s for the first 12 s, then every 5 s30 minutes
video.generate()every 10 s1 hour

Each sleep adds up to 500 ms of jitter. After the budget runs out, wait() throws TaskAsyncTimeoutError. The task itself keeps running, and you can still read it by id. Status reads that fail with a network error, a 404, or a 5xx are retried, up to 20 in a row.

Hold the connection only where that wait is acceptable, such as a script or a background worker. A request handler should store pending.id, respond, and finish in a webhook.

Poll from the browser

image.generateAsync(), image.removeBackgroundAsync(), image.upscaleAsync(), and video.generateAsync() expose the task's pat_ token as pending.access.publicAccessToken when the request sets generate_public_access_token: true. Rate, alt text, and review do not issue one.

// server
const pending = await mynth.image.generateAsync({
  model: "black-forest-labs/flux.2-pro",
  prompt: "A lighthouse at dusk, film grain",
  generate_public_access_token: true,
});

return Response.json({ taskId: pending.id, token: pending.access.publicAccessToken });

The browser calls GET /tasks/{id}/status and GET /tasks/{id}/result with Authorization: Bearer pat_.... Poll for results has the browser loop.

  • The token works only on those two routes and expires one hour after it is issued. A long video render can outlive it.
  • If the task is created but its token cannot be generated, generateAsync() throws MynthAPIError with code public_access_token_failed and the task's id in taskId. Don't resend: poll GET /tasks/{id}/status from the server, or let a webhook report it.
  • wait() is for the server. Its last call is GET /tasks/{id}, which a pat_ cannot make.

Partial results

urls, images, and videos skip failed items. Compare images.length with count when a short list is a problem. A video request renders one video, so a failed render shows up as an empty urls on a completed task. Tasks explains why a completed task can hold failed items.

Next steps

  • Errors: what wait() throws, and how to read the code.
  • Webhooks: take the result without a polling loop.
  • Poll for results: the REST loop.