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 atdata.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 with429, 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 anIdempotency-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.