Unified Video Generation API
curl --request POST \
--url https://www.token-nova.com/v1/video/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [
"<string>"
],
"input_reference": [
"<string>"
],
"duration": 123,
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
'import requests
url = "https://www.token-nova.com/v1/video/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": ["<string>"],
"input_reference": ["<string>"],
"duration": 123,
"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({
model: '<string>',
prompt: '<string>',
image: '<string>',
images: ['<string>'],
input_reference: ['<string>'],
duration: 123,
seconds: '<string>',
size: '<string>',
metadata: {}
})
};
fetch('https://www.token-nova.com/v1/video/generations', 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/video/generations",
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([
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'images' => [
'<string>'
],
'input_reference' => [
'<string>'
],
'duration' => 123,
'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/video/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\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/video/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.token-nova.com/v1/video/generations")
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 \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "video_task_abc123",
"task_id": "video_task_abc123",
"object": "video",
"model": "kling-v1",
"status": "queued",
"progress": 0,
"created_at": 1735689600
}
{
"error": {
"message": "prompt is required",
"type": "new_api_error",
"param": "",
"code": "invalid_request"
}
}
{
"error": {
"message": "Invalid token",
"type": "new_api_error",
"param": "",
"code": "invalid_api_key"
}
}
{
"error": {
"message": "User quota is insufficient",
"type": "new_api_error",
"param": "",
"code": "insufficient_user_quota"
}
}
{
"code": "too_many_requests",
"message": "The upstream load of the current group is saturated, please try again later",
"data": null
}
{
"error": {
"message": "copy_response_body_failed",
"type": "new_api_error",
"param": "",
"code": "bad_response"
}
}
Unified Video Generation API
Submit asynchronous generation tasks using the platform’s unified video task format, compatible with multiple video models and providers.
POST
https://www.token-nova.com
/
v1
/
video
/
generations
Unified Video Generation API
curl --request POST \
--url https://www.token-nova.com/v1/video/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [
"<string>"
],
"input_reference": [
"<string>"
],
"duration": 123,
"seconds": "<string>",
"size": "<string>",
"metadata": {}
}
'import requests
url = "https://www.token-nova.com/v1/video/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": ["<string>"],
"input_reference": ["<string>"],
"duration": 123,
"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({
model: '<string>',
prompt: '<string>',
image: '<string>',
images: ['<string>'],
input_reference: ['<string>'],
duration: 123,
seconds: '<string>',
size: '<string>',
metadata: {}
})
};
fetch('https://www.token-nova.com/v1/video/generations', 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/video/generations",
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([
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'images' => [
'<string>'
],
'input_reference' => [
'<string>'
],
'duration' => 123,
'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/video/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\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/video/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.token-nova.com/v1/video/generations")
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 \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n \"<string>\"\n ],\n \"input_reference\": [\n \"<string>\"\n ],\n \"duration\": 123,\n \"seconds\": \"<string>\",\n \"size\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "video_task_abc123",
"task_id": "video_task_abc123",
"object": "video",
"model": "kling-v1",
"status": "queued",
"progress": 0,
"created_at": 1735689600
}
{
"error": {
"message": "prompt is required",
"type": "new_api_error",
"param": "",
"code": "invalid_request"
}
}
{
"error": {
"message": "Invalid token",
"type": "new_api_error",
"param": "",
"code": "invalid_api_key"
}
}
{
"error": {
"message": "User quota is insufficient",
"type": "new_api_error",
"param": "",
"code": "insufficient_user_quota"
}
}
{
"code": "too_many_requests",
"message": "The upstream load of the current group is saturated, please try again later",
"data": null
}
{
"error": {
"message": "copy_response_body_failed",
"type": "new_api_error",
"param": "",
"code": "bad_response"
}
}
Unified Video Generation API
This is the entry point for multi-vendor video tasks. Requests first enter the unified task protocol, and then the dispatch layer selects the actual channel for execution.- A single entry point supports both text-to-video and image-to-video.
- Asynchronous processing mode; after a successful submission, a public video task ID is returned.
- Supports passing through vendor-specific parameters via
metadata. - Can be used with
/v1/video/generations/{task_id}and/v1/videos/{task_id}to form a complete task flow.
Method and Path
POST /v1/video/generations
Request Example
curl -X POST https://www.token-nova.com/v1/video/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-v1",
"prompt": "A golden retriever running on the beach, with the camera smoothly tracking it",
"duration": 5,
"size": "1280x720",
"metadata": {
"style": "cinematic"
}
}'
import requests
resp = requests.post(
"https://www.token-nova.com/v1/video/generations",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "kling-v1",
"prompt": "A golden retriever running on the beach, with the camera smoothly tracking it",
"duration": 5,
"size": "1280x720",
"metadata": {"style": "cinematic"},
},
timeout=60,
)
print(resp.json())
const response = await fetch("https://www.token-nova.com/v1/video/generations", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "kling-v1",
prompt: "A golden retriever running on the beach, with the camera smoothly tracking it",
duration: 5,
size: "1280x720",
metadata: { style: "cinematic" },
}),
});
console.log(await response.json());
Response Example
{
"id": "video_task_abc123",
"task_id": "video_task_abc123",
"object": "video",
"model": "kling-v1",
"status": "queued",
"progress": 0,
"created_at": 1735689600
}
{
"error": {
"message": "prompt is required",
"type": "new_api_error",
"param": "",
"code": "invalid_request"
}
}
{
"error": {
"message": "Invalid token",
"type": "new_api_error",
"param": "",
"code": "invalid_api_key"
}
}
{
"error": {
"message": "User quota is insufficient",
"type": "new_api_error",
"param": "",
"code": "insufficient_user_quota"
}
}
{
"code": "too_many_requests",
"message": "The upstream load of the current group is saturated, please try again later",
"data": null
}
{
"error": {
"message": "copy_response_body_failed",
"type": "new_api_error",
"param": "",
"code": "bad_response"
}
}
Authentication
Authorization: Bearer YOUR_API_KEY
Body
string
必填
The model name used for billing and dispatch, such as
kling-v1, sora-2, or veo-3. Whether it is ultimately available depends on the current Token’s assigned group and channel configuration.string
Text prompt. It is usually required for pure text-to-video generation; if you are only making light edits based on an image, it is still recommended to provide a clear description.
string
Input image URL or Base64 for image-to-video generation. Together with
images and input_reference, this indicates that visual reference input is present.array<string>
Multi-image reference input. Commonly used for upstreams that require multiple reference images.
string | array<string>
Additional reference materials. Some upstreams treat this as the first frame, reference image, or a collection of materials.
integer
Target duration in seconds. Some channels also accept
seconds; if both are provided, the exact precedence is determined by the adapter.string
Duration field in OpenAI video-compatible style. Common values include
5, 10, and 15.string
Size or ratio hint, such as
1280x720, 720x1280, or 16:9. Whether it is recognized depends on the specific channel.object
Vendor-specific extension parameters, such as
style, negative_prompt, camera_control, aspectRatio, and quality.Response
string
Public task ID on the platform. It can be used directly for subsequent queries and proxy downloads.
string
Task ID field retained for compatibility with legacy APIs, usually the same as
id.string
Fixed to
video.string
Initial status after submission; common values are
queued or in_progress.integer
Task progress percentage. It is usually
0 when first submitted.Use Cases
Text-to-Video
curl -X POST https://www.token-nova.com/v1/video/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3",
"prompt": "A red sports car driving through a rainy night city",
"seconds": "5"
}'
Image-to-Video
curl -X POST https://www.token-nova.com/v1/video/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-v1",
"prompt": "Make the person smile and wave",
"image": "https://.../portrait.png",
"duration": 5
}'
Notes
This route is a unified task entry point and does not guarantee that all channels accept the same set of parameters. Fields not recognized by the adapter may be ignored, or may only take effect for certain models.
