source_url. You have three options:
- Public URL you control — host the file yourself (S3, GCS, CDN, etc.) and pass that URL directly in render/task requests. The renderer fetches it as-is. For video/audio referenced this way you must set
out_point(Framelane can’t probe the duration of a file it doesn’t host). - Framelane upload — upload a local file with
POST /v1/uploads, then use the returnedsource_url. - Auto-ingest a public URL — set
ingest_external: trueon a render and Framelane copies any non-Framelanesource_urlinto your storage before rendering. See Importing public URLs below.
Upload flow
1. Request an upload URL
201 Created):
upload_url expires in 1 hour.
2. Upload the file bytes
PUT the entire file toupload_url with the same Content-Type you declared in step 1. Bytes go directly to GCS — they never pass through the Framelane API.
3. Use source_url in your job
Pass source_url from the upload response as source_url in any render element or task body:
out_point before extraction finishes, the request is rejected with 422 asset_not_ready and nothing is queued. Wait for the asset.ready webhook and resubmit, poll GET /v1/workspace/assets for ready assets, or set out_point yourself to skip the duration lookup entirely.
Importing public URLs
If a render references asource_url that Framelane doesn’t host, set ingest_external: true on the render and Framelane copies each such file into your storage before rendering. This gives you the reliability and metadata of a Framelane-hosted file (including automatic out_point for video/audio) without a separate upload step.
- The render is created in the
ingestingstate and is not sent to the render engine yet. - Framelane copies each non-Framelane source file into your storage. You receive an
asset.readywebhook per file as it completes. - Once every imported file is ready, the render automatically transitions to
queuedand proceeds.out_pointis filled in from the imported file’s duration when omitted. - If a file can’t be imported (unreachable, too large, or unsupported), the render fails with the
ingest_failederror code.
cdn-user.framelane.io source_url from POST /v1/uploads) are never re-copied. Omit ingest_external (or set it to false) to keep the legacy pass-through behavior described in option 1 above.
Supported content types
Unsupported
content_type values return 422 with an unsupported_content_type error
(details.allowed lists the accepted types).
Uploadable is not the same as renderable.
video/x-msvideo (.avi),
video/x-matroska (.mkv) and video/mpeg (.mpg) upload fine, but a video render
element rejects them with 422 — its source_url must end in .mp4, .mov or
.webm. Re-encode before referencing the file in a render..svg sources rasterize in-process on the renderer: flat fills and stroke icons
(Lucide/Feather-style) render; gradients, text and filters inside the SVG do not, so
pre-rasterize those to PNG.

