Skip to content
All pages
  1. Overview
  2. Quick start
  3. Authentication
  4. API reference
    1. GET /media
    2. POST /media
    3. GET /media/{id}/preview
    4. GET /integrations/google/connect
    5. GET /integrations/google
    6. DELETE /integrations/google
    7. GET /integrations/google/folders
    8. POST /media/import
    9. GET /media/imports/{id}
    10. POST /renders
    11. GET /renders/{id}
    12. GET /renders/{id}/download
    13. GET /usage
  5. Code examples
  6. Error handling
  7. Rate limits & quotas
  8. Troubleshooting
  9. Changelog

When it goes wrong

Troubleshooting

Symptom first, because that is what you have in front of you. Every entry is a mistake somebody has actually made or a defect we know about — not an invented FAQ.

422 validation_failed and the field I sent looks fine

CauseThe request shape is strict: an unrecognised field is rejected, not ignored. A typo, a stray url, or a field copied from another API will do it.
FixSend only the fields in the API reference. Start from the minimum — media_id and quote — and add one field at a time.

403 insufficient_scope on a call that worked yesterday

CauseYou are using a different key, and that key was minted without the scope this call needs.
FixCheck the key in Settings → API. Scopes are fixed at mint; re-mint the key with renders:create, renders:read and media:read as needed.

403 tier_not_eligible with a key that authenticates fine

CauseThe key is real but the account’s plan does not include API access. Authentication and eligibility are separate gates.
FixTalk to us about the plan. Nothing about the key or the request will change this.

404 unknown_media on an id I definitely have

CauseThe photo is archived, is not an image, or belongs to another workspace. The render endpoint only accepts what GET /api/v1/media would list.
FixRe-list GET /api/v1/media and use an id from that response. If it is not in the list, it is not renderable.

The render sits at "queued" and progress stays 0

CauseExpected. progress does not move in v1 — it is 0 until the render finishes, then 100. A queued render is normal for the first minute or two.
FixDrive your UI off status, not progress. Only give up at a deadline of 20 minutes or so.

My poll loop runs forever

CauseIt is waiting for "completed" and never checks the other terminal states, so a failed or canceled render never breaks the loop.
FixBranch on completed, failed and canceled explicitly, keep polling on everything else, and give up on a deadline. Both code examples do this.

429 rate_limit_exceeded when starting a batch of renders

CauseThe per-minute limit is on creates. Fanning a work queue out across many workers hits it quickly, because each worker starts renders as fast as it can dequeue them.
FixRate-limit your own producer to the key’s per-minute value, or catch the 429 and requeue with backoff. Ask us to raise the key if the ceiling is genuinely too low for your volume.

402 quota_exceeded on my very first render, with a brand new key

CauseAlmost certainly a Starter plan. Starter can hold an API key and authenticate fine, but it includes zero Pic to Video Renders — so the key works and every create is refused. Two separate gates, and only the second one has anything to do with rendering.
FixCheck GET /api/v1/usage: included: 0 confirms it. Studio is the first plan with an allowance. The read endpoints work on Starter, so you can build the whole integration before you upgrade.

402 spend_cap_reached but usage says I have allowance left

CauseTwo different limits. The spend cap is per key over a rolling 24 hours; the allowance in GET /api/v1/usage is per account per billing cycle.
FixWait for the rolling window to refill, use another key, or ask us to raise that key’s cap.

502 caption_prep_failed

CauseThe caption could not be composited onto the photo, so the render was refused before it started.
FixNothing was charged. Retry; if it repeats on the same photo, try a shorter caption or a different photo and send us the request_id.

asset.url returns 401 in the browser

CauseIt is not a public link. Every URL this API hands back is on our domain and authorised by your API key, not by a token in the URL.
FixFetch it server-side with the Authorization header and host or share the bytes yourself.

I retried a create after a timeout and got charged twice

CauseThe retry went out without an Idempotency-Key, so it was a new request.
FixSend an Idempotency-Key on every create and reuse it on the retry. A replay comes back with Idempotency-Replayed: true.

asset.duration_sec does not match the video

CauseKnown defect: it currently reports render wall-clock rather than the length of the video.
FixProbe the downloaded file. Do not build on that field until this note goes away.
Still stuck? Send the request_id from the failing response to info@omniscape.io. With it we can find the exact call; without it we are guessing.