9. Errors

Status Meaning What to do
400 bad request — unknown operation, invalid file URL, a parameter the operation refused, or a file of the wrong kind the detail names the reason (e.g. font_size: Input should be less than or equal to 12); check service_slug / operation_key / accepts against /studio/tools
401 missing or invalid API key check the X-Api-Key header
402 not enough credits top up
403 not allowed admin-only action
404 not found service, job, or session id is wrong
409 conflict job already finished, or upload link already used
410 upload link expired mint a new one
413 file too large over MAX_UPLOAD_GB or your declared limit
415 file type not allowed check allowed_mime_types on the link
422 validation error pydantic detail array — e.g. an unsafe webhook_url
429 rate limited honor the Retry-After header (seconds)
502 / 503 upstream error / temporarily unavailable retry with exponential backoff

Maintenance windows

During planned maintenance every submitting endpoint (/studio/run, /studio/batch, POST /jobs*, and starting a bridge upload) answers 503 with a machine-readable detail:

{ "detail": { "code": "maintenance", "message": "Back around 18:00 CET" } }

Reads keep working, so a job submitted before the window can still be polled and its result downloaded. Treat code: "maintenance" as "retry later, don't resubmit in a loop" — the message is written for humans and can be shown as-is.

Check ahead of time without submitting anything:

curl -s https://mp.dvocorp.com/api/v1/public/config
# -> {"maintenance":false,"maintenance_message":"", "support":{...}, ...}

Reaching a human

POST /api/v1/public/feedback sends a message straight to our team chat. Send your API key with it (or use the form in the web app — anonymous calls from scripts are refused with 401, same rule as the free studio):

curl -s -X POST https://mp.dvocorp.com/api/v1/public/feedback \
  -H "X-Api-Key: $API_KEY" -H 'Content-Type: application/json' \
  -d '{"message":"circle op fails on 4K input","contact":"[email protected]","error":"job failed: upstream 500"}'
# -> {"ok":true}

message is required (10–2000 chars); contact, page and error are optional context.

This mailbox is a human, not a webhook, so it is tightly limited:

Limit Anonymous (web form) Signed in
Gap between messages 15 min per IP 2 min per account
Per day 5 per IP 20 per account
Per network / hour 10 per /24 (or /64)

Plus a global hourly ceiling, and content rules: at most 2 links, no exact duplicate of a message you already sent that day. Answers are 400 (message rejected — too short, too many links, duplicate), 429 (Retry-After tells you the wait in seconds), or 503 (feedback delivery is not configured — use the contacts from /public/config instead).

Rate limits

All of them return 429 with Retry-After.

Queue delay

Limits decide whether a request is accepted; the plan also decides when the accepted work starts. On a throttled plan a submit still returns 201 and is charged normally, but the job stays queued for a configured hold — and may additionally wait until higher-priority work has finished, up to a fixed cap.

There is no separate status or error for this, and nothing to handle: poll GET /api/v1/jobs/{id} (or wait for the webhook) until done / failed, and size your client timeouts for minutes rather than seconds. If you need guaranteed fast starts, ask about a higher tier.