uploads

Request a file upload URL

Returns a GCS resumable upload URL and the corresponding CDN source URL. PUT your file bytes directly to upload_url with the correct Content-Type header. Once the upload completes, pass source_url as the source_url field in any render or task request.

The upload_url expires in 1 hour. If your network refuses storage.googleapis.com, first_party_upload_url is the same session on a Framelane hostname; PUT there instead.

Alternatively, send the file's bytes as base64 in content_base64 and this one call stores them: the response comes back with uploaded: true and a null upload_url, and source_url works immediately. That route needs no outbound network access of your own — the reason it exists — but it is capped at 256 KB, so it suits logos and icons rather than video.

post/v1/uploads

Request

  • Base URL: https://api.framelane.io
  • URL: https://api.framelane.io/v1/uploads
  • Auth: HTTP bearer

Request body

content_typestring required

MIME type of the file you will upload.

filenamestring nullable

The file's original name. Sets the stored object's extension and is kept as the asset's display name; without it the asset shows as its uuid key.

durationnumber nullable

Optional client-probed media duration in seconds — video and audio only; ignored for images, which have no duration. When provided, the asset is immediately usable/listable instead of waiting on server-side metadata extraction; the server probe (when it runs) overrides it.

widthinteger nullable

Optional client-probed pixel width (video or image).

heightinteger nullable

Optional client-probed pixel height (video or image).

content_base64string nullable

The file's bytes, base64-encoded, to store in this same call. Use it when you cannot reach storage.googleapis.com — a sandboxed agent whose egress is allow-listed per host, typically. The response then carries uploaded: true and a null upload_url, and source_url is usable right away. Capped at 256 KB; larger files must use upload_url. A data: prefix, line wrapping and the URL-safe alphabet are all accepted.

Example request

{
  "content_type": "video/mp4",
  "filename": "my-clip.mp4",
  "duration": 12.5,
  "width": 1920,
  "height": 1080
}

Response

Successful Response

upload_urlstring nullable

GCS resumable upload URL. PUT your file bytes here with the correct Content-Type. null when you sent content_base64: the bytes are already stored, so there is no slot left to fill.

source_urlstring required

CDN URL for the uploaded file. Pass this as source_url in render/task requests.

expires_atstring date-time required

When the upload_url expires (1 hour from now).

uploadedboolean

True when this call also stored the file (you sent content_base64), so source_url is usable immediately. False means only a slot was minted and the bytes are still yours to PUT.

asset_idstring nullable

The media asset registered for this upload — poll it with GET /v1/workspace/assets/{id}. Null for fonts, which are storable but are not timeline media and so get no asset row.

first_party_upload_urlstring nullable

The same upload session as upload_url, on a Framelane hostname. Use it when your network allows *.framelane.io but not storage.googleapis.com — same protocol, same chunks, same expiry. Null when you sent content_base64, or when this deployment has no first-party upload host.

Example response

{
  "upload_url": "https://storage.googleapis.com/framelane-prod-user/uploads/ws_01J.../a1b2c3.mp4?upload_id=...",
  "source_url": "https://cdn-user.framelane.io/uploads/ws_01J.../a1b2c3.mp4",
  "asset_id": "asset_01J8QR2K5VKDGN2T4FBM3CZYX7",
  "first_party_upload_url": "https://uploads.framelane.io/s/AAECAwQFBgcICQoL…"
}

Changes

No recorded changes to this operation across all 1 revision of this API.