Skip to main content

What is a render

A render is an asynchronous job that turns a source asset into a downloadable deliverable — a video (mp4 / mov) or an audio file (m4a / mp3), optionally trimmed to one of the asset’s cuts. It’s its own entity with its own lifecycle, and you can have many renders off one source (a 720p and a 1080p, a full video and an audio-only cut-down).

Triggering a render

curl https://api.roughy.ai/v1/renders \
  -H "Authorization: Bearer $ROUGHY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_id": "<asset_id>",
    "cut_id": "<cut_id>",
    "output": {
      "format": "mp4",
      "resolution": "1080p"
    }
  }'
The response is the render row (state: "pending"); poll GET /v1/renders/{id} until completed, or subscribe to the render.completed / render.failed webhooks.

Output spec

FieldValuesRequired
formatmp4, mov (video) · m4a, mp3 (audio)yes
resolution720p, 1080p, 4k — video onlyno
video_bitrate5, 10, 20, 50 (Mbps) — video onlyno
audio_bitrate128, 192, 256, 320 (kbps)no
format picks the container and the stack: mp4 / mov are video (H.264 + AAC, the same encode in a different container); m4a (AAC) and mp3 are audio-only outputs. Resolution is an aspect-preserving tier, not a fixed width×height. 720p / 1080p / 4k target the shorter edge and scale the source to it without padding, capped to the source — a render never upscales. A landscape source stays landscape, a vertical source stays vertical. Omit resolution to render at the source resolution. resolution and video_bitrate apply to video formats only. Bitrate is a ladder, and optional. Omit video_bitrate / audio_bitrate for Auto (a sensible default for the tier, capped to the source bitrate); set an explicit step to override it. An explicit value above the source is capped to the source — encoding above it only adds bytes.

Applying a cut

A render addresses a specific cut by cut_id (cuts are 1:N per asset). Its presence applies that cut:
  • cut_id present — apply that cut’s kept-segment plan. The cut must belong to the asset and be completed.
  • cut_id omitted — render the full source.
A cut_id that names a cut of this asset which isn’t completed yet returns 409 modifier_not_ready — retry once the cut finalizes.

Source state: video vs audio

What a render needs depends on the output form:
  • A video output reads the full source video, so the asset must be ready. Rendering video in any other state returns 409 asset_not_ready.
  • An audio output reads only the asset’s audio, so it gates on the same cuttable capability as a cut — a not-cuttable asset returns the precise 409 asset_processing / asset_payment_required / asset_failed. For a video whose audio was extracted client-side, an audio render is therefore available while the source video is still uploading.

Validation

A request that’s well-formed but invalid for the target asset returns 422 validation_error:
  • a video format (mp4 / mov) requested for an audio-only asset;
  • resolution or video_bitrate on an audio format;
  • a resolution tier or video_bitrate above a known source;
  • a cut_id that isn’t a cut of this asset.

Idempotency

A render is keyed on the content signature (asset, cut, output):
  • A repeat request with the same signature returns the existing render (200) — no second render, no second charge.
  • A different output (e.g. 1080p instead of 720p, or mp3 instead of m4a) is a separate render (201).
  • A failed render with the same signature is replaced on retry.
Re-runs are free — the credit is charged once per source asset, not per render.

Downloading

GET /v1/renders/{id} includes a short-lived signed download_url once state is completed. The list endpoint omits it — fetch the render to act on it. The URL is valid for about 15 minutes; re-fetch the render for a fresh one rather than caching it.

Cancelling

curl -X DELETE https://api.roughy.ai/v1/renders/{id} \
  -H "Authorization: Bearer $ROUGHY_API_KEY"
Cancel is a hard delete: the render row and any partial output are removed (204). An in-flight render is stopped within seconds. To render again, POST /v1/renders afresh.
  • Cut — the kept-segment plan a render applies.
  • Asset — the source a render reads.
  • Webhooks — push delivery for render terminal states.
  • Credit ledger — why renders are free.