All pages
Reference
POST
/api/v1/renders
Requires the renders:create scope.
Start a render. Returns 202 immediately with an opaque id — the render itself takes about 2 minutes.
This is the only call that costs money
Body fields
The shape is strict. Any field not in this table is 422 validation_failed rather than a silently ignored key — including url, storage_path and preview_url.
| Name | Type | Required | Notes |
|---|---|---|---|
media_id | uuid | yes | A photo id from GET /api/v1/media. |
quote | string ≤500 | no | The caption to burn onto the video. "" is a deliberate no-caption render. |
render_type | "aesthetic_quote" | no | Optional. The only accepted value; anything else is refused. |
caption_style | "quote" | "meme" | no | Caption treatment. |
text_color | "white" | "yellow" | "pastel-yellow" | no | Caption fill. A closed set — a hex value or any other colour name is 422. |
text_size | "tiny" | "smallest" | "smaller" | "default" | "larger" | no | Caption size. Also a closed set. |
bold | boolean | no | Heavier caption weight. |
bold_outline | boolean | no | Outline behind the caption. |
page_theme | string 1–100 | no | A page theme name, if your workspace uses them. |
image_class | "person" | "doll_figurine" | "landscape_nature" | "product_object" | "interior_space" | "other" | no | Override the subject classification. Left off, it is inferred from the photo; set it when the inference is wrong for your material. |
sub_prompt | string ≤150 | no | Extra direction for the generated motion. Optional and advisory — treat its effect as best-effort rather than a guarantee. |
render_prompt | string ≤200 | no | Overrides the generated motion description outright. Same caveat: advisory, and easy to make worse than the default. |
metadata | object | no | Up to 20 scalar keys, echoed back on the render so you can correlate it with your own job. |
Request
curl -s -X POST "https://omniscape.io/api/v1/renders" \
-H "Authorization: Bearer $OMNISCAPE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-job-0001" \
-d '{
"media_id": "c35c8330-5dd2-4170-b2b0-bae80ed7182f",
"quote": "stay soft",
"caption_style": "quote",
"bold": true,
"metadata": { "campaign": "spring" }
}'Response
HTTP/1.1 202 Accepted
X-Request-Id: 0f1c…
{ "object": "render", "id": "rnd_7ef2da3bde9a", "status": "queued" }Notes
- Always send an Idempotency-Key. A repeat with the same key and the same body replays the original response — same render id, no second render, no second charge — and comes back with an Idempotency-Replayed: true header so you can tell. The same key with a different body is 409 idempotency_conflict.
- The request shape is strict: any field not listed above is 422 validation_failed, including url, storage_path and preview_url. There is no way to point the API at an image it does not already hold, which is what makes it safe to expose.
- This is the only call that costs money, and it is refused before anything is charged if the caption cannot be composited (502 caption_prep_failed) or if the key is at its ceiling (402 spend_cap_reached).
- A 202 means queued, not started. Move straight to polling; do not sleep a fixed 6 minutes and check once.
Codes this call can return are on Error handling. If something is behaving unexpectedly, Troubleshooting is organised by symptom.