Skip to main content
In this tutorial you will build an async image flow where:
  1. Your server creates a Mynth task with your API key.
  2. Mynth returns a task ID and a short-lived Public Access Token (PAT).
  3. The browser polls task status and results with that PAT — never with your API key.
By the end you will have a complete create → poll → render path you can drop into an interactive app.

Why this pattern

Task creation (POST /image/generate) requires a Mynth API key. Put that call on the server. GET /tasks/:id/status and GET /tasks/:id/result also accept a task-scoped PAT. That is what the browser uses for live progress without a polling proxy. CORS is open on those two endpoints so browser fetch works from your frontend origin. Other API routes are not open for arbitrary browser origins.

Step 1. Create the task on your server

Keep the SDK and API key server-side only:
generateAsync() returns a TaskAsync immediately. Generation tasks include a PAT by default (task.access.publicAccessToken). Disable it when you only poll from the server with your API key:
About the PAT:
  • JWT string with a pat_ prefix
  • Scoped to this single task ID
  • Valid for one hour (generation PATs)
  • Usable only on GET /tasks/:id/status and GET /tasks/:id/result
Rating and alt text tasks currently do not return a PAT. Poll those from trusted server code with your API key.

Step 2. Return only safe data to the browser

Your app’s API response should include:
  • taskId
  • publicAccessToken
Do not return MYNTH_API_KEY, the full task object from GET /tasks/:id, or other owner-only fields. Example response:

Step 3. Poll status from the browser

Use raw fetch with the PAT as a Bearer token. Do not call the SDK from the browser with your API key, and do not rely on task.wait() in client code — wait() is for server-side use with the SDK client.
Status response:
Possible values: pending, completed, failed.

Step 4. Poll until terminal, then fetch results

A simple client loop:
Successful image.generate result shape:
Handle both task-level and per-image failure:
Notes:
  • A completed task can still include individual status: "failed" images.
  • url can be null when delivery is destination-only; mynth_url is still present on success.
  • GET /tasks/:id/result does not include the owner-only errors array. For full task diagnostics, call GET /tasks/:id from the server with your API key.

Step 5. Map states in the UI

Suggested client behavior:
  • Poll every ~2.5s while the user is waiting (same order of magnitude as the SDK’s fast phase).
  • Stop on completed or failed.
  • Cap wait time (for example 5 minutes).
  • Treat 401/403 as an expired or invalid PAT — start a new generation from the server rather than reusing the token.

What the PAT cannot do

A Public Access Token is not a substitute for your API key. It cannot:
  • Create tasks
  • Access other task IDs
  • Call GET /tasks/:id (full owner-only task details)
For deeper polling options, intervals used by TaskAsync.wait(), and owner-only endpoints, read Async and polling and SDK tasks.

When to use webhooks instead

Polling fits:
  • interactive product flows
  • browser previews
  • short-lived user sessions
Webhooks fit:
  • backend processing after generation
  • durable pipelines
  • systems that should not keep a browser tab open
See Use webhooks when the result should trigger server-side work.