SudoMock
Guide

Async Rendering

Submit a render or PSD upload and get an immediate acknowledgement instead of waiting for the result. Poll the job for its outcome, or let a webhook tell you when it finishes.

Sync vs Async

By default, POST /api/v1/renders and POST /api/v1/psd/upload are synchronous: the request blocks until the work is done and returns the result inline with a 200OK. That is the simplest path and works well for a single render in a request/response cycle.

For long-running work, large batches, or any flow where you do not want to hold a connection open, run the same endpoints asynchronously. Add "is_async": true to the request body and you get an immediate 202Accepted with a render_uuid you can track to completion.

Synchronous (default)Asynchronous (is_async: true)
Response200 with the result inline202 with a render_uuid + status_url
ConnectionHeld open until the work finishesReturns immediately
How you get the resultIn the response bodyPoll the job, or receive a webhook
Best forA single render in a request cycleBatches, long jobs, queue-driven pipelines

Same endpoints, one flag

You do not call a different URL. Set is_async on the existing POST /api/v1/renders and POST /api/v1/psd/upload requests. Video generation is always asynchronous and returns a 202 with no flag needed; see Render Video.

The is_async flag

is_asyncboolean= false

Set to true to process the request in the background. The endpoint responds with 202 Accepted and a render_uuid instead of the inline result. Defaults to false (synchronous).

Async render request body
1{
2 "is_async": true,
3 "mockup_uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
4 "smart_objects": [
5 {
6 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",
7 "asset": {
8 "url": "https://your-domain.com/design.png",
9 "fit": "cover"
10 }
11 }
12 ],
13 "export_options": {
14 "image_format": "webp",
15 "image_size": 1920,
16 "quality": 90
17 }
18}

export_options carry over unchanged

The body is identical to a synchronous render plus is_async: true; all the same export_options apply. The example sets image_size: 1920, which overrides the default of 2048. See the Render Mockup reference for the full export_options list.

The 202 lifecycle

An async submission returns 202Accepted right away. The body echoes back enough to start tracking the job:

202 Accepted (render)
1{
2 "render_uuid": "9d4e2b51-0c7a-4f8e-bb1c-2a6f9e3d8c10",
3 "kind": "render",
4 "status": "queued",
5 "status_url": "/api/v1/jobs/9d4e2b51-0c7a-4f8e-bb1c-2a6f9e3d8c10"
6}

202 Response Fields

render_uuidstringRequired

The job identifier. Pass it to GET /api/v1/jobs/{render_uuid} to track progress and retrieve the result.

kindstringRequired

What the job produces: "render", "video", or "upload". When the job finishes, "render" and "video" expose the downloadable result_url; "upload" exposes a mockup_uuid plus a result_url that deep-links to the new mockup.

statusstringRequired

Initial state, always "queued" on a fresh submission. See the Jobs reference for the full state machine.

status_urlstringRequired

Relative path to poll for this job, equal to /api/v1/jobs/{render_uuid}. Resolve it against the API base URL.

A PSD upload submitted with is_async returns the same shape, with kind set to upload:

202 Accepted (upload)
1{
2 "render_uuid": "1f0a8c23-7b44-4e90-9c2d-55ab1e7f0d33",
3 "kind": "upload",
4 "status": "queued",
5 "status_url": "/api/v1/jobs/1f0a8c23-7b44-4e90-9c2d-55ab1e7f0d33"
6}

Submit, then poll

The async pattern is two steps: submit to get a render_uuid, then poll GET /api/v1/jobs/{render_uuid} until the status is succeeded, failed, or cancelled. Use a gentle backoff so you are not hammering the endpoint.

A job moves through a fixed set of states. The full state machine is documented in the Jobs reference; the states you will observe are:

  • queued: accepted and waiting to start. This is the initial state returned with the 202Accepted.
  • processing: the job is actively running.
  • succeeded: terminal. The result is ready; render and video jobs expose a result_url, and upload jobs expose a mockup_uuid.
  • failed: terminal. The job did not complete; error describes why.
  • cancelled: terminal. The job was cancelled before it finished.

queued and processing are non-terminal: keep polling. succeeded, failed, and cancelled are terminal: stop polling.

Submit and poll
javascript
1const BASE_URL = "https://api.sudomock.com/api/v1";
2const headers = {
3 "Content-Type": "application/json",
4 "x-api-key": "sm_your_api_key",
5};
6
7// 1) Submit asynchronously -> 202 Accepted
8const submit = await fetch(`${BASE_URL}/renders`, {
9 method: "POST",
10 headers,
11 body: JSON.stringify({
12 is_async: true,
13 mockup_uuid: "c315f78f-d2c7-4541-b240-a9372842de94",
14 smart_objects: [{
15 uuid: "128394ee-6758-4f2f-aa36-e2b19b152bd9",
16 asset: { url: "https://your-domain.com/design.png", fit: "cover" },
17 }],
18 }),
19});
20
21const { render_uuid } = await submit.json();
22
23// 2) Poll the job until it is finished
24async function poll(uuid, { intervalMs = 1500, maxMs = 120000 } = {}) {
25 const deadline = Date.now() + maxMs;
26 let delay = intervalMs;
27 while (Date.now() < deadline) {
28 const res = await fetch(`${BASE_URL}/jobs/${uuid}`, { headers });
29 const job = await res.json();
30 if (job.status === "succeeded") return job.result_url;
31 if (job.status === "failed" || job.status === "cancelled") {
32 throw new Error(`Job ${job.status}: ${job.error ?? "unknown"}`);
33 }
34 await new Promise(r => setTimeout(r, delay));
35 delay = Math.min(delay * 1.5, 8000); // gentle backoff, cap at 8s
36 }
37 throw new Error("Timed out waiting for the job to finish");
38}
39
40const resultUrl = await poll(render_uuid);
41console.log("Done:", resultUrl);

Skip polling with webhooks

Instead of polling, register a webhook and SudoMock will POST a signed payload the moment the job finishes. Polling stays available as the source of truth.

SDKs cover async

Official SDKs handle submit + poll for you

The sudomock npm package (npmjs.com/package/sudomock) and the sudomock PyPI package (pypi.org/project/sudomock) cover renders, async submission, video, jobs, and webhooks. They wrap the submit-and-poll loop so you can await a finished result directly.
Async Rendering | SudoMock Docs