curl --request POST \
--url https://roughy-api-staging.fly.dev/v1/renders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"output": {
"frame_rate": 120
},
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://roughy-api-staging.fly.dev/v1/renders"
payload = {
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"output": { "frame_rate": 120 },
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
asset_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
output: {frame_rate: 120},
cut_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://roughy-api-staging.fly.dev/v1/renders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://roughy-api-staging.fly.dev/v1/renders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'asset_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'output' => [
'frame_rate' => 120
],
'cut_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://roughy-api-staging.fly.dev/v1/renders"
payload := strings.NewReader("{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://roughy-api-staging.fly.dev/v1/renders")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://roughy-api-staging.fly.dev/v1/renders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"state": "pending",
"output": {
"format": "mp4",
"resolution": "720p",
"video_bitrate": 5,
"frame_rate": 120,
"audio_bitrate": 128
},
"size_bytes": 123,
"error_code": "<string>",
"error_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"state": "pending",
"output": {
"format": "mp4",
"resolution": "720p",
"video_bitrate": 5,
"frame_rate": 120,
"audio_bitrate": 128
},
"size_bytes": 123,
"error_code": "<string>",
"error_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "not_found",
"message": "Asset not found."
}
}{
"error": {
"code": "conflict",
"message": "The source asset isn't `ready` (`asset_not_ready`) — every render reads the original upload, so it must be fully uploaded and settled. Or the requested `cut_id` exists but isn't `completed` yet (`modifier_not_ready`)."
}
}{
"error": {
"code": "validation_error",
"message": "The output is invalid for this asset (`validation_error`): a video format on an audio asset, a `resolution` / `video_bitrate` above the source, or a `cut_id` that isn't a cut of this asset.",
"fields": [
{
"field": "body.name",
"message": "Field required"
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Per-user rate limit exceeded; honour `Retry-After`."
}
}Render an asset
Render an asset to a video (mp4/mov) or audio (m4a/mp3) output.
Idempotent on the full request shape: an identical request returns the
existing render.
curl --request POST \
--url https://roughy-api-staging.fly.dev/v1/renders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"output": {
"frame_rate": 120
},
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://roughy-api-staging.fly.dev/v1/renders"
payload = {
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"output": { "frame_rate": 120 },
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
asset_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
output: {frame_rate: 120},
cut_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://roughy-api-staging.fly.dev/v1/renders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://roughy-api-staging.fly.dev/v1/renders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'asset_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'output' => [
'frame_rate' => 120
],
'cut_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://roughy-api-staging.fly.dev/v1/renders"
payload := strings.NewReader("{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://roughy-api-staging.fly.dev/v1/renders")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://roughy-api-staging.fly.dev/v1/renders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"asset_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"output\": {\n \"frame_rate\": 120\n },\n \"cut_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"state": "pending",
"output": {
"format": "mp4",
"resolution": "720p",
"video_bitrate": 5,
"frame_rate": 120,
"audio_bitrate": 128
},
"size_bytes": 123,
"error_code": "<string>",
"error_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"asset_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cut_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"state": "pending",
"output": {
"format": "mp4",
"resolution": "720p",
"video_bitrate": 5,
"frame_rate": 120,
"audio_bitrate": 128
},
"size_bytes": 123,
"error_code": "<string>",
"error_message": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "not_found",
"message": "Asset not found."
}
}{
"error": {
"code": "conflict",
"message": "The source asset isn't `ready` (`asset_not_ready`) — every render reads the original upload, so it must be fully uploaded and settled. Or the requested `cut_id` exists but isn't `completed` yet (`modifier_not_ready`)."
}
}{
"error": {
"code": "validation_error",
"message": "The output is invalid for this asset (`validation_error`): a video format on an audio asset, a `resolution` / `video_bitrate` above the source, or a `cut_id` that isn't a cut of this asset.",
"fields": [
{
"field": "body.name",
"message": "Field required"
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Per-user rate limit exceeded; honour `Retry-After`."
}
}Authorizations
Pass your API key as Authorization: Bearer sk_…. Mint a key from your dashboard's API-keys page.
Body
Response
A render with the same inputs already exists; it is returned.
A render.
Render id.
The source asset this render was produced from.
The cut applied to this render, or null for a full-source render.
Render lifecycle state: pending / processing while the render encodes, completed when ready, failed on error. completed and failed are terminal.
pending, processing, completed, failed The output spec this render was produced with.
Show child attributes
Show child attributes
Output size in bytes.
Machine-readable failure code when state=failed.
Human-readable failure detail when state=failed.
When the render was created.
When encoding started.
When the render reached a terminal state.