OpenAI-Compatible Video Interface
curl --request POST \
--url https://www.token-nova.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"task_id": "<string>",
"video_id": "<string>",
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
'import requests
url = "https://www.token-nova.com/v1/videos"
payload = {
"task_id": "<string>",
"video_id": "<string>",
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
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({
task_id: '<string>',
video_id: '<string>',
model: '<string>',
prompt: '<string>',
image: '<string>',
seconds: '<string>',
size: '<string>',
metadata: {}
})
};
fetch('https://www.token-nova.com/v1/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://www.token-nova.com/v1/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([
'task_id' => '<string>',
'video_id' => '<string>',
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'seconds' => '<string>',
'size' => '<string>',
'metadata' => [
]
]),
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://www.token-nova.com/v1/videos"
payload := strings.NewReader("{\n \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\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://www.token-nova.com/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.token-nova.com/v1/videos")
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 \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1735689600,
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "completed",
"progress": 100,
"created_at": 1735689600,
"completed_at": 1735689900,
"video_url": "https://...",
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "failed",
"progress": 100,
"created_at": 1735689600,
"error": {
"message": "Content policy violation",
"code": "content_policy"
}
}
{
"error": {
"message": "task_origin_not_exist",
"type": "new_api_error",
"param": "",
"code": "task_not_exist"
}
}
OpenAI-Compatible Video Interface
Use OpenAI Videos-style create, query, remix, and content proxy routing operations for video tasks.
POST
https://www.token-nova.com
/
v1
/
videos
OpenAI-Compatible Video Interface
curl --request POST \
--url https://www.token-nova.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"task_id": "<string>",
"video_id": "<string>",
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
'import requests
url = "https://www.token-nova.com/v1/videos"
payload = {
"task_id": "<string>",
"video_id": "<string>",
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
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({
task_id: '<string>',
video_id: '<string>',
model: '<string>',
prompt: '<string>',
image: '<string>',
seconds: '<string>',
size: '<string>',
metadata: {}
})
};
fetch('https://www.token-nova.com/v1/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://www.token-nova.com/v1/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([
'task_id' => '<string>',
'video_id' => '<string>',
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'seconds' => '<string>',
'size' => '<string>',
'metadata' => [
]
]),
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://www.token-nova.com/v1/videos"
payload := strings.NewReader("{\n \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\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://www.token-nova.com/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.token-nova.com/v1/videos")
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 \"task_id\": \"<string>\",\n \"video_id\": \"<string>\",\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1735689600,
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "completed",
"progress": 100,
"created_at": 1735689600,
"completed_at": 1735689900,
"video_url": "https://...",
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "failed",
"progress": 100,
"created_at": 1735689600,
"error": {
"message": "Content policy violation",
"code": "content_policy"
}
}
{
"error": {
"message": "task_origin_not_exist",
"type": "new_api_error",
"param": "",
"code": "task_not_exist"
}
}
OpenAI-Compatible Video Interface
This set of routes presents itself externally in an OpenAI Videos API style, suitable for clients that already read and write results asvideo objects.
- Creation, querying, and remix all use the OpenAI-style
videoobject. - The exposed
idmaps to the platform task ID, rather than directly exposing the upstream raw task ID. - The
contentproxy route supports access via API Key and logged-in session state. - Remix will preferentially look up the original video task and lock execution to the original channel.
Route List
| Method | Path | Description |
|---|---|---|
POST | /v1/videos | Create a video task |
GET | /v1/videos/{task_id} | Query a video task |
POST | /v1/videos/{video_id}/remix | Remix based on an existing video task |
GET | /v1/videos/{task_id}/content | Proxy download of video content |
Request Examples
curl -X POST https://www.token-nova.com/v1/videos \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "A paper airplane flies through a bright office, with the camera smoothly following",
"seconds": "5",
"size": "1280x720"
}'
import requests
resp = requests.post(
"https://www.token-nova.com/v1/videos",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "sora-2",
"prompt": "A paper airplane flies through a bright office, with the camera smoothly following",
"seconds": "5",
"size": "1280x720",
},
timeout=60,
)
print(resp.json())
const response = await fetch("https://www.token-nova.com/v1/videos", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "sora-2",
prompt: "A paper airplane flies through a bright office, with the camera smoothly following",
seconds: "5",
size: "1280x720",
}),
});
console.log(await response.json());
Response Examples
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1735689600,
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "completed",
"progress": 100,
"created_at": 1735689600,
"completed_at": 1735689900,
"video_url": "https://...",
"seconds": "5",
"size": "1280x720"
}
{
"id": "video_abc123",
"task_id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "failed",
"progress": 100,
"created_at": 1735689600,
"error": {
"message": "Content policy violation",
"code": "content_policy"
}
}
{
"error": {
"message": "task_origin_not_exist",
"type": "new_api_error",
"param": "",
"code": "task_not_exist"
}
}
Authentication
Creation, querying, and remix use Bearer Token:Authorization: Bearer YOUR_API_KEY
GET /v1/videos/{task_id}/content also supports:
Authorization: Bearer YOUR_API_KEY- Web dashboard login state
UserAuth
Path Parameters
string
必填
Video task ID, used for querying and content proxying.
string
必填
The source video ID for remix. The server will first look up the original task and original channel using it.
Body
string
必填
Video model name, such as
sora-2, sora_video2, or a model name mapped from another channel.string
必填
Video description or remix instruction.
string
Input image for image-to-video generation. Support depends on the specific upstream provider.
string
Target video duration, common values are
5, 10, and 15.string
Target resolution or ratio, such as
1280x720, 720x1280, or 16:9.object
Vendor passthrough parameters. For remix, upstream proprietary fields can also be included here.
Response
string
Public video task ID.
string
Task status, common values are
queued, in_progress, completed, and failed.string
Playable URL after generation is complete. In many cases, it points to the platform proxy route.
object
Error details for failed tasks, shown only when
status = failed.Usage Scenarios
Query a Task
curl https://www.token-nova.com/v1/videos/video_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
Remix
curl -X POST https://www.token-nova.com/v1/videos/video_abc123/remix \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "Keep the composition, but change the scene to a neon-lit nighttime style"
}'
Proxy Download
curl -L https://www.token-nova.com/v1/videos/video_abc123/content \
-H "Authorization: Bearer YOUR_API_KEY" \
--output output.mp4
Notes
If you have both
/v1/video/generations and /v1/videos integrated, it is recommended that the frontend consistently choose one response structure to use, and avoid mixing the generic task wrapper and the OpenAI video object within the same parsing logic.