curl --request GET \
--url 'https://api.mixroute.ai/v1/video/generations/download?id=video_xxx' \
--header 'Authorization: Bearer sk-xxxxxxxxxx'
import requests
url = "https://api.mixroute.ai/v1/video/generations/download"
params = {"id": "video_xxx"}
headers = {"Authorization": "Bearer sk-xxxxxxxxxx"}
response = requests.get(url, params=params, headers=headers)
print(response.json())
const response = await fetch('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx', {
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx'
}
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->get('https://api.mixroute.ai/v1/video/generations/download', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx'
],
'query' => ['id' => 'video_xxx']
]);
echo $response->getBody();
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.mixroute.ai/v1/video/generations/download?id=video_xxx", nil)
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/video/generations/download?id=video_xxx"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
response = http.request(request)
puts response.body
{
"success": true,
"generation_id": "video_xxx",
"task_id": "video_xxx",
"format": "mp4",
"size": 15728640,
"base64": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE...",
"data_url": "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE..."
}
Video Series
Download Video
Download completed video file data
GET
/
v1
/
video
/
generations
/
download
curl --request GET \
--url 'https://api.mixroute.ai/v1/video/generations/download?id=video_xxx' \
--header 'Authorization: Bearer sk-xxxxxxxxxx'
import requests
url = "https://api.mixroute.ai/v1/video/generations/download"
params = {"id": "video_xxx"}
headers = {"Authorization": "Bearer sk-xxxxxxxxxx"}
response = requests.get(url, params=params, headers=headers)
print(response.json())
const response = await fetch('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx', {
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx'
}
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->get('https://api.mixroute.ai/v1/video/generations/download', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx'
],
'query' => ['id' => 'video_xxx']
]);
echo $response->getBody();
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.mixroute.ai/v1/video/generations/download?id=video_xxx", nil)
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/video/generations/download?id=video_xxx"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
response = http.request(request)
puts response.body
{
"success": true,
"generation_id": "video_xxx",
"task_id": "video_xxx",
"format": "mp4",
"size": 15728640,
"base64": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE...",
"data_url": "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE..."
}
Introduction
The download video endpoint is used to retrieve completed video file data.This endpoint is only supported by Sora 2 model. Other models (Veo, Doubao Seedance) return the video URL directly in the query task response, no additional download step required.
Authentication
Bearer Token, e.g.,Bearer sk-xxxxxxxxxx
Query Parameters
string
required
Video ID, the
task_id returned by the query task endpointcURL Example
curl -X GET "https://api.mixroute.ai/v1/video/generations/download?id=video_69095b4ce0048190893a01510c0c98b0" \
-H "Authorization: Bearer sk-xxxxxxxxxx"
Response Example
{
"success": true,
"generation_id": "video_69095b4ce0048190893a01510c0c98b0",
"task_id": "video_69095b4ce0048190893a01510c0c98b0",
"format": "mp4",
"size": 15728640,
"base64": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAB...",
"data_url": "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAB..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the request was successful |
generation_id | string | Generation ID (same as videoId) |
task_id | string | Task ID |
format | string | Video format (fixed to "mp4") |
size | number | Video file size (bytes) |
base64 | string | Base64 encoded video data |
data_url | string | Data URL format video data, can be used directly in frontend <video> tag |
Usage Guide
Using data_url in Frontend
Thedata_url field can be used directly in HTML <video> tag:
<video src="data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAB..." controls></video>
Download and Save File
JavaScript Example
// Get base64 data from response
const response = await fetch('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx', {
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx'
}
});
const data = await response.json();
// Convert base64 to Blob
const binaryString = atob(data.base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const blob = new Blob([bytes], { type: 'video/mp4' });
// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'video.mp4';
a.click();
URL.revokeObjectURL(url);
Python Example
import requests
import base64
def download_video(video_id, api_key):
"""Download video and save as file"""
url = f"https://api.mixroute.ai/v1/video/generations/download?id={video_id}"
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(url, headers=headers)
data = response.json()
if data.get("success"):
# Decode base64 data
video_data = base64.b64decode(data["base64"])
# Save to file
with open("video.mp4", "wb") as f:
f.write(video_data)
print(f"✅ Video saved: video.mp4 (size: {data['size']} bytes)")
return True
else:
print("❌ Download failed")
return False
Complete Workflow Example (Sora 2)
1. Submit Video Generation Task
curl -X POST "https://api.mixroute.ai/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "A cute kitten playing in the garden",
"seconds": "4",
"size": "720x1280"
}'
{
"task_id": "video_69095b4ce0048190893a01510c0c98b0",
"status": "submitted",
"format": "mp4"
}
2. Query Task Status (Poll Until Success)
curl -X GET "https://api.mixroute.ai/v1/video/generations/video_69095b4ce0048190893a01510c0c98b0" \
-H "Authorization: Bearer sk-xxxxxxxxxx"
succeeded, proceed to the next step.
3. Download Video File
curl -X GET "https://api.mixroute.ai/v1/video/generations/download?id=video_69095b4ce0048190893a01510c0c98b0" \
-H "Authorization: Bearer sk-xxxxxxxxxx"
Notes
- The download endpoint returns Base64 encoded video data, suitable for direct display in frontend or saving
- For large files, consider using streaming download or direct URL download
- Video format is fixed to MP4
curl --request GET \
--url 'https://api.mixroute.ai/v1/video/generations/download?id=video_xxx' \
--header 'Authorization: Bearer sk-xxxxxxxxxx'
import requests
url = "https://api.mixroute.ai/v1/video/generations/download"
params = {"id": "video_xxx"}
headers = {"Authorization": "Bearer sk-xxxxxxxxxx"}
response = requests.get(url, params=params, headers=headers)
print(response.json())
const response = await fetch('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx', {
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx'
}
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->get('https://api.mixroute.ai/v1/video/generations/download', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx'
],
'query' => ['id' => 'video_xxx']
]);
echo $response->getBody();
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.mixroute.ai/v1/video/generations/download?id=video_xxx", nil)
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/video/generations/download?id=video_xxx"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/video/generations/download?id=video_xxx')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
response = http.request(request)
puts response.body
{
"success": true,
"generation_id": "video_xxx",
"task_id": "video_xxx",
"format": "mp4",
"size": 15728640,
"base64": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE...",
"data_url": "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE..."
}
⌘I