- Your server creates a Mynth task with your API key.
- Mynth returns a task ID and a short-lived Public Access Token (PAT).
- The browser polls task status and results with that PAT — never with your API key.
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:
- JWT string with a
pat_prefix - Scoped to this single task ID
- Valid for one hour (generation PATs)
- Usable only on
GET /tasks/:id/statusandGET /tasks/:id/result
Step 2. Return only safe data to the browser
Your app’s API response should include:taskIdpublicAccessToken
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 rawfetch 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.
pending, completed, failed.
Step 4. Poll until terminal, then fetch results
A simple client loop:image.generate result shape:
- A completed task can still include individual
status: "failed"images. urlcan benullwhen delivery is destination-only;mynth_urlis still present on success.GET /tasks/:id/resultdoes not include the owner-onlyerrorsarray. For full task diagnostics, callGET /tasks/:idfrom 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
completedorfailed. - 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)
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
- backend processing after generation
- durable pipelines
- systems that should not keep a browser tab open