Skip to main content
Mynth work is task-based. POST /image/generate always returns a task (taskId + optional Public Access Token). The SDK generate() method creates that task and polls until it finishes. Use this guide when you need to wait for results or poll yourself. For browser UI polling with a Public Access Token, see Browser Polling. For push delivery instead of polling, see Use Webhooks.

Wait in the SDK (simplest path)

On a server (or any place that holds your API key), use generate(). It returns a completed result wrapper:
import Mynth from "@mynthio/sdk";

const mynth = new Mynth({
  apiKey: process.env.MYNTH_API_KEY,
});

const result = await mynth.image.generate({
  prompt: "Minimal product shot of a matte black espresso grinder",
  model: "google/gemini-3.1-flash-image",
});

console.log(result.urls); // string[]
rate() and alt() work the same way: they start a task with sync: false and poll until completion.

Start a task without waiting

Use generateAsync() when you need the task ID immediately — for example to return to a client, store the ID, or wait later:
const task = await mynth.image.generateAsync({
  prompt: "Minimal product shot of a matte black espresso grinder",
  model: "google/gemini-3.1-flash-image",
});

console.log(task.id);
console.log(task.access.publicAccessToken); // pat_... (generation only, by default)

const result = await task.wait();
console.log(result.urls);
Also available: rateAsync(), altAsync(). Those return a TaskAsync without a Public Access Token — poll them from trusted code with your API key.
MethodReturnsWaits?
generate() / rate() / alt()Result wrapperYes (wait() under the hood)
generateAsync() / rateAsync() / altAsync()TaskAsyncNo — call task.wait() yourself

Handle success and failure

task.wait() resolves only when the task status is completed. It throws dedicated errors otherwise:
import {
  TaskAsyncTimeoutError,
  TaskAsyncTaskFailedError,
  TaskAsyncUnauthorizedError,
  TaskAsyncFetchError,
  TaskAsyncTaskFetchError,
} from "@mynthio/sdk";

try {
  const result = await task.wait();
  console.log(result.urls);
} catch (error) {
  if (error instanceof TaskAsyncTaskFailedError) {
    // Task status is "failed"
  } else if (error instanceof TaskAsyncTimeoutError) {
    // Polled for five minutes without completion
  } else if (error instanceof TaskAsyncUnauthorizedError) {
    // API key or Public Access Token rejected
  } else if (error instanceof TaskAsyncFetchError) {
    // Transient status fetches failed after retries
  } else if (error instanceof TaskAsyncTaskFetchError) {
    // Final task detail fetch failed
  } else {
    throw error;
  }
}
Task statuses:
StatusMeaning
pendingQueued or still running
completedFinished; result payload is available
failedDid not complete; see task errors if present
A completed image.generate task can still contain per-image failures (images[].status: "failed"). Use result.getImages() for successes only, or result.getImages({ includeFailed: true }) for both.

Poll with REST

Create a generation task (always async at the API):
curl https://api.mynth.io/image/generate \
  -X POST \
  -H "Authorization: Bearer $MYNTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Minimal product shot of a matte black espresso grinder",
    "model": "google/gemini-3.1-flash-image"
  }'
{
  "data": {
    "taskId": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
    "estimatedCost": "0.03",
    "access": {
      "publicAccessToken": "pat_eyJhbGciOi..."
    }
  }
}

Poll status

GET /tasks/:id/status accepts your API key or the task’s Public Access Token:
curl https://api.mynth.io/tasks/$TASK_ID/status \
  -H "Authorization: Bearer $PUBLIC_ACCESS_TOKEN"
{
  "data": {
    "status": "pending"
  }
}
Poll until completed or failed.

Fetch the result

GET /tasks/:id/result uses the same auth options. It returns id, type, status, and result (null while pending or when a failed task has no result):
curl https://api.mynth.io/tasks/$TASK_ID/result \
  -H "Authorization: Bearer $PUBLIC_ACCESS_TOKEN"
Completed generate example:
{
  "data": {
    "id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
    "type": "image.generate",
    "status": "completed",
    "result": {
      "model": "google/gemini-3.1-flash-image",
      "images": [
        {
          "status": "success",
          "id": "img_...",
          "url": "https://...",
          "mynth_url": "https://...",
          "cost": "0.03",
          "size": "1024x1024"
        }
      ]
    }
  }
}

Owner-only full task

GET /tasks/:id requires your Mynth API key (not a Public Access Token). Use it when you need the original request, full result, cost, timestamps, or errors:
curl https://api.mynth.io/tasks/$TASK_ID \
  -H "Authorization: Bearer $MYNTH_API_KEY"
See Tasks reference for the full shape.

Public Access Tokens

Generation responses include a task-scoped Public Access Token by default (access.pat.enabled defaults to true). The token:
  • is a JWT prefixed with pat_
  • is scoped to one task
  • is valid for one hour
  • works only on GET /tasks/:id/status and GET /tasks/:id/result
Disable it when you only poll from the server with an API key:
const task = await mynth.image.generateAsync({
  prompt: "...",
  model: "google/gemini-3.1-flash-image",
  access: { pat: { enabled: false } },
});
Do not put your API key in the browser. Return only taskId and publicAccessToken to clients — see Browser Polling. rate and alt tasks do not currently return a Public Access Token. Poll those with your API key from trusted server code.

SDK polling behavior

TaskAsync.wait():
BehaviorDetail
StartLazy — polling begins on first wait() call
DedupMultiple wait() calls share one promise
Interval~2.5s for the first 12s, then ~5s (with jitter)
Timeout5 minutes → TaskAsyncTimeoutError
Status authPrefers the task Public Access Token; falls back to the client API key
Final fetchGET /tasks/:id with the client API key after status: "completed"
Transient failuresRetries up to 7 times; counter resets after a successful status poll
Failed taskstatus: "failed"TaskAsyncTaskFailedError
Because the final detail fetch uses the API key, call wait() from code that has the SDK client configured with your key. Browser clients should poll /status and /result with the Public Access Token instead. Full SDK helpers and error classes: SDK tasks.

REST sync mode for rate and alt

Unlike image generation, POST /image/rate and POST /image/alt default to server-side sync ("sync": true). The API waits up to ~55 seconds and returns results inline when possible. Set "sync": false (or use rateAsync() / altAsync()) to get a pending task and poll yourself. If sync mode times out, the API returns a 202 pending task — poll the same task endpoints.

Choose a completion strategy

ApproachBest when
SDK generate() / wait()Server code can block until the task finishes
REST poll /status + /resultYou own the HTTP client or poll from the browser with a PAT
WebhooksBackend pipelines, durable side effects, multi-system fan-out

How async fits generation

  1. You create a task (POST /image/generate, or generate / generateAsync in the SDK).
  2. Mynth queues work and returns taskId (and usually a Public Access Token).
  3. You wait in the SDK, poll /status then /result, or receive a webhook.
  4. On completed, read images (or rate/alt results) from the result payload.
Creating a task does not return final media in the create response. Always wait, poll, or subscribe before treating the job as done.