Generate Video Overview
This tutorial uses the implemented OpenAI-compatible video routes with a Sora-type channel, including submission, polling, and download. Choose an enabled video model supporting this route; other channel types may use different fields and responses.
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/videos | Submit |
| GET | /v1/videos/{id} | Poll status |
| GET | /v1/videos/{id}/content | Download |
API Calls in Multiple Languages
See language setup. Set API_KEY and replace model, file URL, and ID placeholders first. Each version displays the raw response to the same request.
These examples submit a task only. Keep the returned id for subsequent queries.
curl --fail-with-body --silent --show-error --max-time 180 \
--request POST \
--url "https://api.tokatlas.ai/v1/videos" \
--header "Authorization: Bearer $API_KEY" \
--form model=YOUR_ENABLED_SORA_MODEL_ID \
--form 'prompt=A ceramic cup on a table, steam rising, slow camera movement' \
--form seconds=4 \
--form size=720x1280import os
import requests
headers = {
'Authorization': 'Bearer ' + os.environ["API_KEY"],
}
files = {'model': (None, 'YOUR_ENABLED_SORA_MODEL_ID'),
'prompt': (None, 'A ceramic cup on a table, steam rising, slow camera movement'),
'seconds': (None, '4'),
'size': (None, '720x1280')}
response = requests.request(
'POST', 'https://api.tokatlas.ai/v1/videos', headers=headers,
files=files,
timeout=180,
)
response.raise_for_status()
print(response.text)if (!process.env.API_KEY) throw new Error("Set API_KEY first.");
const form = new FormData();
form.append("model", "YOUR_ENABLED_SORA_MODEL_ID");
form.append("prompt", "A ceramic cup on a table, steam rising, slow camera movement");
form.append("seconds", "4");
form.append("size", "720x1280");
const response = await fetch("https://api.tokatlas.ai/v1/videos", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.API_KEY,
},
body: form,
signal: AbortSignal.timeout(180_000),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(await response.text());import java.net.URI;
import java.net.http.*;
import java.time.Duration;
public class Example {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("API_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalArgumentException("Set API_KEY first.");
}
String boundary = "TokatlasExampleBoundary";
String payload =
"--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nYOUR_ENABLED_SORA_MODEL_ID\r\n" +
"--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nA ceramic cup on a table, steam rising, slow camera movement\r\n" +
"--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"seconds\"\r\n\r\n4\r\n" +
"--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"size\"\r\n\r\n720x1280\r\n" +
"--TokatlasExampleBoundary--\r\n";
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30)).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.tokatlas.ai/v1/videos"))
.timeout(Duration.ofSeconds(180))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.method("POST", HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException("HTTP " + response.statusCode() + ": "
+ response.body());
}
System.out.println(response.body());
}
}Query the Task
Replace YOUR_TASK_ID with the submission response’s id. Poll at intervals until status is completed or failed; do not submit new tasks while waiting.
curl --fail-with-body --silent --show-error --max-time 180 \
--request GET \
--url "https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID" \
--header "Authorization: Bearer $API_KEY"import os
import requests
headers = {
'Authorization': 'Bearer ' + os.environ["API_KEY"],
}
response = requests.request(
'GET', 'https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID', headers=headers,
timeout=180,
)
response.raise_for_status()
print(response.text)if (!process.env.API_KEY) throw new Error("Set API_KEY first.");
const response = await fetch("https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID", {
method: "GET",
headers: {
"Authorization": "Bearer " + process.env.API_KEY,
},
signal: AbortSignal.timeout(180_000),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(await response.text());import java.net.URI;
import java.net.http.*;
import java.time.Duration;
public class Example {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("API_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalArgumentException("Set API_KEY first.");
}
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30)).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID"))
.timeout(Duration.ofSeconds(180))
.header("Authorization", "Bearer " + apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException("HTTP " + response.statusCode() + ": "
+ response.body());
}
System.out.println(response.body());
}
}Download the Result
Run only when the status is completed. Use the same task ID; success saves video.mp4.
curl --fail-with-body --silent --show-error --max-time 180 \
--request GET \
--url "https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID/content" \
--header "Authorization: Bearer $API_KEY" \
--output video.mp4import os
from pathlib import Path
import requests
headers = {
'Authorization': 'Bearer ' + os.environ["API_KEY"],
}
response = requests.request(
'GET', 'https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID/content', headers=headers,
timeout=180,
)
response.raise_for_status()
Path('video.mp4').write_bytes(response.content)
print("Saved video.mp4")import { writeFile } from "node:fs/promises";
if (!process.env.API_KEY) throw new Error("Set API_KEY first.");
const response = await fetch("https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID/content", {
method: "GET",
headers: {
"Authorization": "Bearer " + process.env.API_KEY,
},
signal: AbortSignal.timeout(180_000),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
await writeFile("video.mp4", Buffer.from(await response.arrayBuffer()));
console.log("Saved video.mp4");import java.net.URI;
import java.net.http.*;
import java.time.Duration;
import java.nio.file.*;
public class Example {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("API_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalArgumentException("Set API_KEY first.");
}
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30)).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.tokatlas.ai/v1/videos/YOUR_TASK_ID/content"))
.timeout(Duration.ofSeconds(180))
.header("Authorization", "Bearer " + apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<byte[]> response = client.send(
request, HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException("HTTP " + response.statusCode() + ": "
+ new String(response.body(), java.nio.charset.StandardCharsets.UTF_8));
}
Files.write(Path.of("video.mp4"), response.body());
System.out.println("Saved video.mp4");
}
}1. Prepare
Install Python 3 and set your key and enabled Sora-compatible model ID. The example uses 4 seconds and 720×1280; select a model supporting those settings.
python3 -m pip install requests
export API_KEY='YOUR_TOKATLAS_API_KEY'
export VIDEO_MODEL_ID='YOUR_ENABLED_SORA_MODEL_ID'2. Submit, Wait, and Download
Save as generate_video.py and run python3 generate_video.py. It saves video-task.txt immediately; running again resumes polling that task. Rename the ID file to preserve it before starting a new task. Avoid repeated submissions while an outcome is unknown.
import os
import time
from pathlib import Path
import requests
base = os.environ.get("API_BASE_URL", "https://api.tokatlas.ai").rstrip("/")
headers = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
task_file = Path("video-task.txt")
if task_file.exists():
task_id = task_file.read_text().strip()
else:
response = requests.post(
base + "/v1/videos", headers=headers,
files={"model": (None, os.environ["VIDEO_MODEL_ID"]),
"prompt": (None, "A ceramic cup on a table, steam rising, slow camera movement"),
"seconds": (None, "4"), "size": (None, "720x1280")},
timeout=120,
)
response.raise_for_status()
body = response.json()
task_id = body["id"]
task_file.write_text(task_id)
print("Task:", task_id)
for attempt in range(120):
response = requests.get(base + f"/v1/videos/{task_id}", headers=headers, timeout=60)
response.raise_for_status()
task = response.json()
status = task.get("status")
print(status, task.get("progress", ""))
if status == "completed":
with requests.get(base + f"/v1/videos/{task_id}/content",
headers=headers, stream=True, timeout=120) as download:
download.raise_for_status()
with Path("video.mp4").open("wb") as output:
for chunk in download.iter_content(1024 * 1024):
output.write(chunk)
print("Saved video.mp4")
break
if status == "failed":
raise RuntimeError(task.get("error") or task)
if status not in {"queued", "in_progress"}:
raise RuntimeError(f"Unexpected task response: {task}")
time.sleep(5)
else:
raise TimeoutError("Task still pending; run again to resume polling the saved ID")3. Interpret the Result
queued and in_progress are pending states. completed triggers download to video.mp4; inspect error when failed. The polling limit stops local waiting, not the remote task. Run again later to resume polling.
Troubleshooting
400: check model, seconds, and pixel dimensions. Do not use an image aspect ratio such as1:1as videosize.401/403: check the key and access to the video model.- Task not found: use the returned public
idand a key belonging to the submitting account. - Download failure: check for
completed; retain the task ID and error body. - Timeout or
5xx: resume querying a saved ID. If submission returned no ID, check request records before resubmitting.
See File Analysis for image input and Tool Calling for chat integration.
