curl --request POST \
--url https://console.spatius.ai/v1/open/videos \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-App-ID: <api-key>' \
--data '
{
"avatarId": "d385dd22-9200-4806-94a0-dce464ca916d",
"audioUrl": "https://example.com/media/speech.wav",
"name": "Welcome video",
"requestId": "9628ee92-d5d9-4eac-bf2a-39cd3f804f02",
"video": {
"width": 1024,
"height": 1024
}
}
'import requests
url = "https://console.spatius.ai/v1/open/videos"
payload = {
"avatarId": "d385dd22-9200-4806-94a0-dce464ca916d",
"audioUrl": "https://example.com/media/speech.wav",
"name": "Welcome video",
"requestId": "9628ee92-d5d9-4eac-bf2a-39cd3f804f02",
"video": {
"width": 1024,
"height": 1024
}
}
headers = {
"X-App-ID": "<api-key>",
"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-App-ID': '<api-key>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
avatarId: 'd385dd22-9200-4806-94a0-dce464ca916d',
audioUrl: 'https://example.com/media/speech.wav',
name: 'Welcome video',
requestId: '9628ee92-d5d9-4eac-bf2a-39cd3f804f02',
video: {width: 1024, height: 1024}
})
};
fetch('https://console.spatius.ai/v1/open/videos', 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://console.spatius.ai/v1/open/videos",
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([
'avatarId' => 'd385dd22-9200-4806-94a0-dce464ca916d',
'audioUrl' => 'https://example.com/media/speech.wav',
'name' => 'Welcome video',
'requestId' => '9628ee92-d5d9-4eac-bf2a-39cd3f804f02',
'video' => [
'width' => 1024,
'height' => 1024
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-App-ID: <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://console.spatius.ai/v1/open/videos"
payload := strings.NewReader("{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-App-ID", "<api-key>")
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://console.spatius.ai/v1/open/videos")
.header("X-App-ID", "<api-key>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://console.spatius.ai/v1/open/videos")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-App-ID"] = '<api-key>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}"
response = http.request(request)
puts response.read_body{
"jobId": "6f1e2b3c-9a1d-4e5f-8b0a-2c4d6e8f0a1b",
"status": "queued",
"createdAt": "2026-09-12T09:00:00Z"
}{
"error": {
"code": "invalid_request",
"message": "Invalid video request or presentation settings.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "unauthorized",
"message": "Unauthorized.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "forbidden",
"message": "Video API access is not configured.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "conflict",
"message": "requestId was already used for a different video request",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Open API rate limit exceeded.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "internal_error",
"message": "An internal error occurred.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "service_unavailable",
"message": "Video generation is unavailable; retry later.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}Create a Video
Accepts an Avatar ID and public audio URL, saves a job, and immediately returns its ID. Media processing happens asynchronously; poll the job every 15 seconds until it succeeds, fails, or expires.
Video access must be enabled separately from Avatar creation. Apps owned by one account share video jobs, retry keys, and independent video rate limits. Accepted jobs count toward creation limits even if processing later fails. The Console API does not impose an active-video-job quota; the video service manages execution concurrency.
Use requestId to retry uncertain submissions without creating another render. A retry returns the existing job’s current state. Use a new requestId to render again after a terminal failure.
curl --request POST \
--url https://console.spatius.ai/v1/open/videos \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-App-ID: <api-key>' \
--data '
{
"avatarId": "d385dd22-9200-4806-94a0-dce464ca916d",
"audioUrl": "https://example.com/media/speech.wav",
"name": "Welcome video",
"requestId": "9628ee92-d5d9-4eac-bf2a-39cd3f804f02",
"video": {
"width": 1024,
"height": 1024
}
}
'import requests
url = "https://console.spatius.ai/v1/open/videos"
payload = {
"avatarId": "d385dd22-9200-4806-94a0-dce464ca916d",
"audioUrl": "https://example.com/media/speech.wav",
"name": "Welcome video",
"requestId": "9628ee92-d5d9-4eac-bf2a-39cd3f804f02",
"video": {
"width": 1024,
"height": 1024
}
}
headers = {
"X-App-ID": "<api-key>",
"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-App-ID': '<api-key>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
avatarId: 'd385dd22-9200-4806-94a0-dce464ca916d',
audioUrl: 'https://example.com/media/speech.wav',
name: 'Welcome video',
requestId: '9628ee92-d5d9-4eac-bf2a-39cd3f804f02',
video: {width: 1024, height: 1024}
})
};
fetch('https://console.spatius.ai/v1/open/videos', 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://console.spatius.ai/v1/open/videos",
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([
'avatarId' => 'd385dd22-9200-4806-94a0-dce464ca916d',
'audioUrl' => 'https://example.com/media/speech.wav',
'name' => 'Welcome video',
'requestId' => '9628ee92-d5d9-4eac-bf2a-39cd3f804f02',
'video' => [
'width' => 1024,
'height' => 1024
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-App-ID: <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://console.spatius.ai/v1/open/videos"
payload := strings.NewReader("{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-App-ID", "<api-key>")
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://console.spatius.ai/v1/open/videos")
.header("X-App-ID", "<api-key>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://console.spatius.ai/v1/open/videos")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-App-ID"] = '<api-key>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"avatarId\": \"d385dd22-9200-4806-94a0-dce464ca916d\",\n \"audioUrl\": \"https://example.com/media/speech.wav\",\n \"name\": \"Welcome video\",\n \"requestId\": \"9628ee92-d5d9-4eac-bf2a-39cd3f804f02\",\n \"video\": {\n \"width\": 1024,\n \"height\": 1024\n }\n}"
response = http.request(request)
puts response.read_body{
"jobId": "6f1e2b3c-9a1d-4e5f-8b0a-2c4d6e8f0a1b",
"status": "queued",
"createdAt": "2026-09-12T09:00:00Z"
}{
"error": {
"code": "invalid_request",
"message": "Invalid video request or presentation settings.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "unauthorized",
"message": "Unauthorized.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "forbidden",
"message": "Video API access is not configured.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "conflict",
"message": "requestId was already used for a different video request",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Open API rate limit exceeded.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "internal_error",
"message": "An internal error occurred.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "service_unavailable",
"message": "Video generation is unavailable; retry later.",
"requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}
}Authorizations
Your Spatius App ID.
The API key bound to the App ID.
Body
An existing public Avatar, an Avatar actively assigned to your account, or an Avatar explicitly allowed for your account. Access is checked on every creation and before rendering.
Audio source in WAV format only, at most 500 MiB and no longer than 20 minutes. Use a public HTTP(S) URL without embedded credentials. Signed query parameters are supported. Keep the URL accessible for the preparation window of up to 30 minutes. Each transfer has a five-minute limit. The source must return a supported Content-Type; application/octet-stream is not supported. See Media requirements.
1 - 4096^https?://[^/?#@\s]+([/?#].*)?$Optional background image, at most 50 MiB. Use a public HTTP(S) URL without embedded credentials. Signed query parameters are supported. Keep the URL accessible for the preparation window of up to 30 minutes. Each transfer has a five-minute limit. The source must return a supported Content-Type; application/octet-stream is not supported. See Media requirements. Its pixel dimensions determine omitted output dimensions according to the Output sizing rules.
1 - 4096^https?://[^/?#@\s]+([/?#].*)?$Optional job name. When omitted, Spatius generates a name from the job ID.
1 - 128Optional retry key, shared across Apps owned by your account. The same requestId and normalized input return the existing job without consuming creation quota again. Different input with the same key returns HTTP 409. Omitted video.width, video.height, and video.fit are distinct from explicit values, even if output is identical. Other omitted presentation settings remain equivalent to their documented defaults. Keep the key and request body unchanged when retrying an uncertain response. Requests accepted before the change to background-based sizing can return 409 on replay even with the original body; check the existing job before submitting a new requestId. Omit this field to create a new job on every call.
Optional presentation settings. When both dimensions are omitted and the background image dimensions are available, output follows the image size, scaled down proportionally to fit the limits and rounded down to even dimensions with a minimum of 64 pixels. If only one dimension is supplied, the missing dimension follows the background aspect ratio with the same rounding and minimum. Without usable background dimensions, each omitted dimension falls back to 1024. An invalid derived size can fail the job during preparation. Explicit dimensions must be even, from 64 to 1920, with an effective product at most 2,073,600 pixels; request validation substitutes 1024 for an omitted dimension. Omitted width, height, and fit remain distinct from explicit values for retry comparison. Encoding settings are managed by Spatius. Opening and closing transitions are included even when lead-in and lead-out are zero. See Output sizing.
Show child attributes
Show child attributes
Response
Job accepted, or an existing job returned for a retry.
The accepted job ID.
New jobs return queued. A retry returns the existing job's current status, which may already be terminal.
queued, processing, succeeded, failed, expired Original acceptance time, including on a retry.

