Skip to main content
Every SudoMock endpoint is a server endpoint. Calls go to https://api.sudomock.com and carry your key in the x-api-key header. Keys begin with sm_.

The key stays on your side

None of the endpoints are meant to be called from a browser. The key authorises renders and spends credits, so a key that reaches a page bundle should be treated as leaked and replaced from the dashboard. Put the call behind your own route and read the key from your environment. The one surface a browser touches is the embedded editor, and it does not use your key either: your server opens a Studio session and the browser receives a short lived token instead. Issue one key per integration and name it after the thing that holds it, so a leak costs you that integration rather than the rest of your business. GET /api/v1/me is the cheapest way to prove a key is live, because it returns the account behind the key, the plan and the credits left. Authentication covers issuing and revoking.

A call returns the image or a job

A render returns the finished image at data.print_files[0].export_path. Send is_async as true and the same call answers with a job instead, which you follow over a webhook or poll at GET /api/v1/jobs/{job_id}. Queue the work whenever nobody is sitting in front of it. A queued render does not hold a concurrency slot while it waits, which is what makes a large batch practical: submit the whole set, then follow the jobs. Artwork goes in as a public image URL or as base64, so a file already sitting in your own storage needs no upload step first.

Two ceilings, both answering 429

The sustained rate is 1,000 requests per minute. Separately, a per plan ceiling counts how many renders run at once. Both answer with 429, and error.type tells them apart: a rate limit means slow down, a concurrency limit means wait for work already in flight. Read Retry-After rather than guessing a delay. Do not hardcode the parallel numbers. GET /api/v1/packages/plans returns max_concurrent_requests and max_concurrent_uploads for the plan you are on. Size your worker pool from those two fields and a 429 becomes something you rarely meet. Rate limits and concurrency limits holds the headers that report both ceilings on every response.

Retries that do not cost twice

Send an Idempotency-Key on an upload. Reusing the same key with a different body answers 409 rather than creating a second template. A render that never produced an image is refunded to the balance it was drawn from, so a failed call does not quietly cost credits. A 5xx is ours and is safe to retry with backoff. Errors holds every error_code behind the statuses and a retry loop you can copy.

Start with an SDK

The official SDKs set the header from an environment variable and handle retries and response parsing for you, so the parts above become configuration rather than code you maintain. Read SDKs before writing HTTP calls by hand, and Quickstart for a first render end to end.