Skip to main content
POST
/
v3
/
hyperframes
/
renders
Create HyperFrames Render
curl --request POST \
  --url https://api.heygen.com/v3/hyperframes/renders \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '
{
  "project": {
    "type": "<string>",
    "url": "<string>"
  },
  "fps": 30,
  "quality": "standard",
  "format": "mp4",
  "resolution": "1080p",
  "aspect_ratio": "16:9",
  "composition": "<string>",
  "variables": {},
  "title": "<string>",
  "callback_id": "<string>",
  "callback_url": "<string>"
}
'
import requests

url = "https://api.heygen.com/v3/hyperframes/renders"

payload = {
"project": {
"type": "<string>",
"url": "<string>"
},
"fps": 30,
"quality": "standard",
"format": "mp4",
"resolution": "1080p",
"aspect_ratio": "16:9",
"composition": "<string>",
"variables": {},
"title": "<string>",
"callback_id": "<string>",
"callback_url": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
project: {type: '<string>', url: '<string>'},
fps: 30,
quality: 'standard',
format: 'mp4',
resolution: '1080p',
aspect_ratio: '16:9',
composition: '<string>',
variables: {},
title: '<string>',
callback_id: '<string>',
callback_url: '<string>'
})
};

fetch('https://api.heygen.com/v3/hyperframes/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://api.heygen.com/v3/hyperframes/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([
'project' => [
'type' => '<string>',
'url' => '<string>'
],
'fps' => 30,
'quality' => 'standard',
'format' => 'mp4',
'resolution' => '1080p',
'aspect_ratio' => '16:9',
'composition' => '<string>',
'variables' => [

],
'title' => '<string>',
'callback_id' => '<string>',
'callback_url' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);

$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://api.heygen.com/v3/hyperframes/renders"

payload := strings.NewReader("{\n \"project\": {\n \"type\": \"<string>\",\n \"url\": \"<string>\"\n },\n \"fps\": 30,\n \"quality\": \"standard\",\n \"format\": \"mp4\",\n \"resolution\": \"1080p\",\n \"aspect_ratio\": \"16:9\",\n \"composition\": \"<string>\",\n \"variables\": {},\n \"title\": \"<string>\",\n \"callback_id\": \"<string>\",\n \"callback_url\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("x-api-key", "<api-key>")
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://api.heygen.com/v3/hyperframes/renders")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"project\": {\n \"type\": \"<string>\",\n \"url\": \"<string>\"\n },\n \"fps\": 30,\n \"quality\": \"standard\",\n \"format\": \"mp4\",\n \"resolution\": \"1080p\",\n \"aspect_ratio\": \"16:9\",\n \"composition\": \"<string>\",\n \"variables\": {},\n \"title\": \"<string>\",\n \"callback_id\": \"<string>\",\n \"callback_url\": \"<string>\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.heygen.com/v3/hyperframes/renders")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"project\": {\n \"type\": \"<string>\",\n \"url\": \"<string>\"\n },\n \"fps\": 30,\n \"quality\": \"standard\",\n \"format\": \"mp4\",\n \"resolution\": \"1080p\",\n \"aspect_ratio\": \"16:9\",\n \"composition\": \"<string>\",\n \"variables\": {},\n \"title\": \"<string>\",\n \"callback_id\": \"<string>\",\n \"callback_url\": \"<string>\"\n}"

response = http.request(request)
puts response.read_body
{
  "data": {
    "render_id": "<string>"
  }
}
{
"error": {
"code": "invalid_parameter",
"message": "Composition zip is invalid or missing index.html.",
"param": "project",
"doc_url": null
}
}
{
"error": {
"code": "authentication_failed",
"message": "Invalid or expired API key. Verify your x-api-key header.",
"param": null,
"doc_url": null
}
}
{
"error": {
"code": "request_in_progress",
"message": "A request with this Idempotency-Key is already in progress. Retry shortly.",
"param": null,
"doc_url": null
}
}
{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Retry after the duration specified in the Retry-After header.",
"param": null,
"doc_url": null
}
}

Authorizations

x-api-key
string
header
required

HeyGen API key. Obtain from your HeyGen dashboard.

Headers

Idempotency-Key
string

Optional client-supplied key for safely retrying mutations. Subsequent calls within 24 hours that share this key replay the original response — even if the request body differs slightly (a warning is logged). A retry that arrives while the original is still in flight gets a 409 request_in_progress. Keys must be 1–255 characters from [A-Za-z0-9_:.-]; a UUID is a safe default. Scope is per-endpoint and per-resource: the same key on a different route or path parameter is independent.

Required string length: 1 - 255
Pattern: ^[A-Za-z0-9_\-:.]{1,255}$

Body

application/json

Request body for POST /v3/hyperframes/renders.

project
AssetUrl · object
required

Asset input via publicly accessible HTTPS URL.

fps
integer | null
default:30

Output frames per second. Defaults to 30 if not provided.

Required range: 1 <= x <= 240
quality
enum<string>
default:standard

Render quality preset; higher quality is slower.

Available options:
draft,
standard,
high
format
enum<string>
default:mp4

Output container/codec.

Available options:
mp4,
webm,
mov
resolution
enum<string>
default:1080p

Output resolution tier. Defaults to '1080p'. Pass '4k' for 4K renders (billed at 1.5x).

Available options:
1080p,
4k
aspect_ratio
enum<string>
default:16:9

Output aspect ratio. Defaults to '16:9' (landscape). Pass '9:16' for portrait or '1:1' for square.

Available options:
16:9,
9:16,
1:1
composition
string | null

Entry HTML file relative to the project root (e.g. compositions/intro.html). Defaults to index.html when omitted.

Maximum string length: 512
variables
Variables · object | null

Optional overrides for the composition's data-composition-variables. Use this to parameterise a single composition across multiple renders.

title
string | null

Free-text label for the render; echoed back in detail responses.

Maximum string length: 500
callback_id
string | null

Opaque client tracking ID, echoed back in webhook payloads.

Maximum string length: 256
callback_url
string | null

Per-request HTTPS webhook URL the render fires when it terminates.

Response

Accepted — submission acknowledged; poll for completion.

data
CreateHyperframesRenderResponse · object

Response for POST /v3/hyperframes/renders.