Video Generation
Generate videos from a text prompt or reference image.
Video generation is asynchronous. POST /v1/videos/generations submits the task and returns an id; poll GET /v1/videos/{video_id} until status is "completed", then download the file via GET /v1/videos/{video_id}/content.
Parameters
Endpoint: POST /v1/videos/generations
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model ID, e.g. wan-2.7, hailuo-2.3, veo-2.0-generate-001, gen4_turbo, seedance-01-lite, kling-v2-master, seedance-2.0, veo-3.1-generate. |
prompt | string | Yes | Text description of the desired video. |
input_reference | string | file | No | Reference image URL or uploaded file for image-to-video mode. |
seconds | integer | No | Duration in seconds. |
size | string | No | Legacy resolution parameter, e.g. 1920x1080. Prefer extra_body.resolution with extra_body.aspect_ratio. |
extra_body | object | No | Provider-specific extension parameters (see below). |
user | string | No | End-user identifier, passed through as-is. |
Passing Reference Assets
| Goal | Field to pass |
|---|---|
| Single image-to-video request with one reference image | input_reference |
| Multiple reference images, or explicit multimodal reference mode | extra_body.reference_image_urls |
| Use reference videos to guide generation | extra_body.reference_video_urls |
| Use reference audio to guide generation | extra_body.reference_audio_urls |
| Specify first frame or start/end frames | extra_body.first_frame_url / extra_body.last_frame_url |
input_reference and reference_image_urls have different semantics even when they contain the same image. input_reference is the primary single reference image for standard image-to-video requests. reference_image_urls is a multimodal reference list that the model may use for subject, style, composition, or consistency. You can pass one image in reference_image_urls, but only do this when you explicitly want multimodal reference behavior. If extra_body.reference_image_urls is set explicitly, input_reference will not override it.
extra_body Common Fields
| Field | Type | Description |
|---|---|---|
resolution | string | Resolution: 480p, 720p, 1080p, or 4k. |
aspect_ratio | string | Aspect ratio: 16:9, 9:16, 1:1, 4:3, 3:4, or 21:9. |
audio_url | string | External audio URL. |
generate_audio | boolean | Whether to automatically generate audio for the video. |
video_url | string | Reference video URL for reference-to-video mode with Seedance. |
first_frame_url | string | First-frame URL for first-frame or start/end-frame generation. |
first_image | string | Alternative first-frame field accepted by compatible providers. |
last_frame_url | string | Last-frame URL for start/end-frame generation. |
last_image | string | Alternative last-frame field accepted by compatible providers. |
reference_image_urls | string[] | Multimodal reference image URLs. |
reference_video_urls | string[] | Multimodal reference video URLs. |
reference_audio_urls | string[] | Multimodal reference audio URLs. |
enhance_prompt | boolean | Prompt enhancement for Veo. Defaults to true. |
prompt_optimization | boolean | Prompt optimization for Pixwith. Defaults to true. |
subject_reference | list | Subject references for Flora. |
watermark | boolean | Watermark option for Seedance. Defaults to false. |
Model Capability Fields
Call /model_group/info before submitting a request to check whether a model supports a specific video capability.
| Field | Type | Description |
|---|---|---|
supports_video_multimodal_reference | boolean | Whether the model supports reference_image_urls, reference_video_urls, and reference_audio_urls. |
supports_video_start_end_frame | boolean | Whether the model supports start/end-frame generation. |
How It Works
Video generation follows a three-step flow:
Step 1 — Submit the task (POST /v1/videos/generations)
The request returns immediately with an id and status: "processing".
Step 2 — Poll for the result (GET /v1/videos/{video_id})
Repeat the poll request every few seconds until status is "completed".
Step 3 — Download the video (GET /v1/videos/{video_id}/content)
Fetch the binary video file once the task is complete.
| Status | Meaning |
|---|---|
processing | Video is being generated |
completed | Done — ready to download |
failed | Generation failed — see error field |
All Language Examples
curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" }}'curl -X POST https://silkdock.ai/v1/videos/generations ^-H "Authorization: Bearer %SILKDOCK_API_KEY%" ^-H "Content-Type: application/json" ^-d "{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks","seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}"http POST https://silkdock.ai/v1/videos/generations \Authorization:"Bearer $SILKDOCK_API_KEY" \model=seedance-2.0 \prompt="Ocean waves crashing on rocks, sunlight refracting into rainbows" \seconds:=10 \extra_body:='{"resolution":"1080p","aspect_ratio":"16:9"}'wget -q -O - https://silkdock.ai/v1/videos/generations \--method=POST \--header="Authorization: Bearer $SILKDOCK_API_KEY" \--header="Content-Type: application/json" \--body-data='{ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" }}'$headers = @{ "Authorization" = "Bearer $env:SILKDOCK_API_KEY" "Content-Type" = "application/json"}$body = @{ model = "seedance-2.0" prompt = "Ocean waves crashing on rocks, sunlight refracting into rainbows" seconds = 10 extra_body = @{ resolution = "1080p" aspect_ratio = "16:9" }} | ConvertTo-Json -Depth 5$res = Invoke-RestMethod -Method POST ` -Uri "https://silkdock.ai/v1/videos/generations" ` -Headers $headers ` -Body $bodyWrite-Output $res.idconst res = await fetch("https://silkdock.ai/v1/videos/generations", {method: "POST",headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },}),});const data = await res.json();console.log(data.id);import axios from "axios";const { data } = await axios.post("https://silkdock.ai/v1/videos/generations",{ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },},{ headers: { Authorization: `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json", },});console.log(data.id);$.ajax({url: "https://silkdock.ai/v1/videos/generations",method: "POST",contentType: "application/json",headers: { Authorization: `Bearer ${SILKDOCK_API_KEY}`,},data: JSON.stringify({ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },}),success(res) { console.log(res.id);},});const xhr = new XMLHttpRequest();xhr.open("POST", "https://silkdock.ai/v1/videos/generations");xhr.setRequestHeader("Authorization", `Bearer ${process.env.SILKDOCK_API_KEY}`);xhr.setRequestHeader("Content-Type", "application/json");xhr.onload = () => {const data = JSON.parse(xhr.responseText);console.log(data.id);};xhr.send(JSON.stringify({model: "seedance-2.0",prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows",seconds: 10,extra_body: { resolution: "1080p", aspect_ratio: "16:9",},}));const request = require("request");request.post({ url: "https://silkdock.ai/v1/videos/generations", headers: { Authorization: `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json", }, json: { model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", }, },},(err, res, body) => { console.log(body.id);});const unirest = require("unirest");unirest.post("https://silkdock.ai/v1/videos/generations").headers({ Authorization: `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",}).send({ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },}).then((res) => { console.log(res.body.id);});import OpenAI from "openai";const client = new OpenAI({apiKey: process.env.SILKDOCK_API_KEY,baseURL: "https://silkdock.ai/v1",});const video = await client.videos.create({model: "seedance-2.0",prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows",seconds: 10,extra_body: { resolution: "1080p", aspect_ratio: "16:9",},});let result = video;while (result.status === "processing") {await new Promise((resolve) => setTimeout(resolve, 5000));result = await client.videos.retrieve(video.id);}console.log("Done:", result.status);const res = await fetch("https://silkdock.ai/v1/videos/generations", {method: "POST",headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },}),});const { id } = await res.json() as { id: string };console.log(id);from openai import OpenAIimport osimport timeclient = OpenAI( api_key=os.getenv("SILKDOCK_API_KEY"), base_url="https://silkdock.ai/v1",)video = client.videos.create( model="seedance-2.0", prompt="Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds=10, extra_body={ "resolution": "1080p", "aspect_ratio": "16:9", },)while True: result = client.videos.retrieve(video.id) if result.status == "completed": break if result.status == "failed": raise RuntimeError(result.error) time.sleep(5)content = client.videos.retrieve_content(video.id)with open("out.mp4", "wb") as f: f.write(content.read())import requests, osres = requests.post( "https://silkdock.ai/v1/videos/generations", headers={"Authorization": f"Bearer {os.getenv('SILKDOCK_API_KEY')}"}, json={ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" }, },)print(res.json()["id"])#include <stdio.h>#include <curl/curl.h>int main(void) { CURL *curl = curl_easy_init(); if (!curl) return 1; struct curl_slist *headers = NULL; headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "Authorization: Bearer " SILKDOCK_API_KEY); const char *body = "{"model":"seedance-2.0"," ""prompt":"Ocean waves crashing on rocks"," ""seconds":10," ""extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}"; curl_easy_setopt(curl, CURLOPT_URL, "https://silkdock.ai/v1/videos/generations"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); curl_easy_perform(curl); curl_slist_free_all(headers); curl_easy_cleanup(curl); return 0;}/* compile: gcc main.c -lcurl -o main */#import <Foundation/Foundation.h>NSURLSession *session = [NSURLSession sharedSession];NSURL *url = [NSURL URLWithString:@"https://silkdock.ai/v1/videos/generations"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];[request setHTTPMethod:@"POST"];[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];[request setValue:[@"Bearer " stringByAppendingString: [NSProcessInfo.processInfo.environment objectForKey:@"SILKDOCK_API_KEY"]] forHTTPHeaderField:@"Authorization"];NSDictionary *payload = @{ @"model": @"seedance-2.0", @"prompt": @"Ocean waves crashing on rocks, sunlight refracting into rainbows", @"seconds": @10, @"extra_body": @{ @"resolution": @"1080p", @"aspect_ratio": @"16:9" }};[request setHTTPBody:[NSJSONSerialization dataWithJSONObject:payload options:0 error:nil]];NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"Video ID: %@", json[@"id"]); }];[task resume];import java.net.http.*;import java.net.URI;var req = HttpRequest.newBuilder() .uri(URI.create("https://silkdock.ai/v1/videos/generations")) .header("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString( """{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks, sunlight refracting into rainbows","seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}""")) .build();System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());import okhttp3.*;OkHttpClient client = new OkHttpClient();RequestBody body = RequestBody.create( "{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks"," + ""seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}", MediaType.get("application/json"));Request request = new Request.Builder() .url("https://silkdock.ai/v1/videos/generations") .addHeader("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .post(body) .build();try (Response response = client.newCall(request).execute()) { System.out.println(response.body().string());}import kong.unirest.Unirest;var res = Unirest.post("https://silkdock.ai/v1/videos/generations") .header("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .header("Content-Type", "application/json") .body("{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks"," + ""seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}") .asString();System.out.println(res.getBody());package mainimport ( "bytes" "encoding/json" "fmt" "io" "net/http" "os")func main() { body, _ := json.Marshal(map[string]any{ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": map[string]any{ "resolution": "1080p", "aspect_ratio": "16:9", }, }) req, _ := http.NewRequest("POST", "https://silkdock.ai/v1/videos/generations", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+os.Getenv("SILKDOCK_API_KEY")) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) fmt.Println(string(data))}<?php$ch = curl_init("https://silkdock.ai/v1/videos/generations");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "model" => "seedance-2.0", "prompt" => "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds" => 10, "extra_body" => [ "resolution" => "1080p", "aspect_ratio" => "16:9", ], ]),]);$res = json_decode(curl_exec($ch), true);echo $res["id"];<?phprequire_once "HTTP/Request2.php";$request = new HTTP_Request2( "https://silkdock.ai/v1/videos/generations", HTTP_Request2::METHOD_POST);$request->setHeader([ "Authorization" => "Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type" => "application/json",]);$request->setBody(json_encode([ "model" => "seedance-2.0", "prompt" => "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds" => 10, "extra_body" => [ "resolution" => "1080p", "aspect_ratio" => "16:9", ],]));$res = json_decode($request->send()->getBody(), true);echo $res["id"];<?phpuse GuzzleHttpClient;$client = new Client();$res = $client->post("https://silkdock.ai/v1/videos/generations", [ "headers" => [ "Authorization" => "Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type" => "application/json", ], "json" => [ "model" => "seedance-2.0", "prompt" => "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds" => 10, "extra_body" => [ "resolution" => "1080p", "aspect_ratio" => "16:9", ], ],]);$body = json_decode($res->getBody(), true);echo $body["id"];<?php$client = new httpClient;$request = new httpClientRequest( "POST", "https://silkdock.ai/v1/videos/generations");$request->setHeaders([ "Authorization" => "Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type" => "application/json",]);$body = new httpMessageBody;$body->append(json_encode([ "model" => "seedance-2.0", "prompt" => "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds" => 10, "extra_body" => [ "resolution" => "1080p", "aspect_ratio" => "16:9", ],]));$request->setBody($body);$client->enqueue($request)->send();$res = json_decode($client->getResponse()->getBody(), true);echo $res["id"];import Foundationvar req = URLRequest(url: URL(string: "https://silkdock.ai/v1/videos/generations")!)req.httpMethod = "POST"req.setValue("Bearer \(ProcessInfo.processInfo.environment["SILKDOCK_API_KEY"]!)", forHTTPHeaderField: "Authorization")req.setValue("application/json", forHTTPHeaderField: "Content-Type")req.httpBody = try! JSONSerialization.data(withJSONObject: [ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": [ "resolution": "1080p", "aspect_ratio": "16:9" ],])let (data, _) = try! await URLSession.shared.data(for: req)print(String(data: data, encoding: .utf8)!)require "net/http"require "json"uri = URI("https://silkdock.ai/v1/videos/generations")req = Net::HTTP::Post.new(uri)req["Authorization"] = "Bearer #{ENV['SILKDOCK_API_KEY']}"req["Content-Type"] = "application/json"req.body = {model: "seedance-2.0",prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows",seconds: 10,extra_body: { resolution: "1080p", aspect_ratio: "16:9",},}.to_jsonres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }puts JSON.parse(res.body)["id"]import java.net.http.*import java.net.URIval req = HttpRequest.newBuilder() .uri(URI.create("https://silkdock.ai/v1/videos/generations")) .header("Authorization", "Bearer ${System.getenv("SILKDOCK_API_KEY")}") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString( """{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks, sunlight refracting into rainbows","seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}""")) .build()println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body())use reqwest::blocking::Client;use serde_json::json;fn main() -> Result<(), Box<dyn std::error::Error>> { let res = Client::new() .post("https://silkdock.ai/v1/videos/generations") .header("Authorization", format!("Bearer {}", std::env::var("SILKDOCK_API_KEY")?)) .json(&json!({ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" } })) .send()?; println!("{}", res.text()?); Ok(())}POST /v1/videos/generations HTTP/1.1Host: silkdock.aiAuthorization: Bearer <YOUR_API_KEY>Content-Type: application/json{"model": "seedance-2.0","prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows","seconds": 10,"extra_body": { "resolution": "1080p", "aspect_ratio": "16:9"}}import 'dart:convert';import 'package:http/http.dart' as http;void main() async {final res = await http.post( Uri.parse('https://silkdock.ai/v1/videos/generations'), headers: { 'Authorization': 'Bearer ${const String.fromEnvironment("SILKDOCK_API_KEY")}', 'Content-Type': 'application/json', }, body: jsonEncode({ 'model': 'seedance-2.0', 'prompt': 'Ocean waves crashing on rocks, sunlight refracting into rainbows', 'seconds': 10, 'extra_body': { 'resolution': '1080p', 'aspect_ratio': '16:9', }, }),);final data = jsonDecode(res.body);print(data['id']);}library(httr2)req <- request("https://silkdock.ai/v1/videos/generations") |>req_headers( Authorization = paste("Bearer", Sys.getenv("SILKDOCK_API_KEY")), "Content-Type" = "application/json") |>req_body_json(list( model = "seedance-2.0", prompt = "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds = 10, extra_body = list( resolution = "1080p", aspect_ratio = "16:9" )))resp <- req_perform(req)cat(resp_body_json(resp)$id)(* requires cohttp-lwt-unix *)open Cohttp_lwt_unixopen Cohttpopen Lwtlet () =let body = {|{"model":"seedance-2.0","prompt":"Ocean waves crashing on rocks, sunlight refracting into rainbows","seconds":10,"extra_body":{"resolution":"1080p","aspect_ratio":"16:9"}}|} inlet headers = Header.of_list [ "Authorization", "Bearer " ^ Sys.getenv "SILKDOCK_API_KEY"; "Content-Type", "application/json";] inLwt_main.run ( Client.post ~headers ~body:(Cohttp_lwt.Body.of_string body) (Uri.of_string "https://silkdock.ai/v1/videos/generations") >>= fun (_, body) -> Cohttp_lwt.Body.to_string body >>= fun s -> print_string s; return_unit)curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" }}'curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "wan-2.7", "prompt": "The subject starts running as the camera slowly pulls back", "input_reference": "https://example.com/reference.jpg", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "4:3" }}'input_reference is passed as a regular reference image and does not automatically become first_frame_url. For first-frame or start/end-frame generation, pass extra_body.first_frame_url and optionally extra_body.last_frame_url explicitly. Check /model_group/info for supports_video_start_end_frame before using this mode. For multimodal reference image, video, or audio lists, check supports_video_multimodal_reference.
curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "seedance-2.0", "prompt": "The camera slowly pushes in from the front and ends on a night city silhouette", "seconds": 6, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9", "first_frame_url": "https://example.com/first.png", "last_frame_url": "https://example.com/last.png" }}'curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "seedance-2.0", "prompt": "A dancer spins to the beat", "seconds": 10, "extra_body": { "resolution": "720p", "aspect_ratio": "1:1", "audio_url": "https://example.com/music.mp3" }}'curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "veo-3.1-generate", "prompt": "Birdsong echoes through a forest", "seconds": 8, "size": "1920x1080"}'curl -X GET "https://silkdock.ai/model_group/info?model_group=seedance-2.0" \-H "Authorization: Bearer $SILKDOCK_API_KEY"supports_video_start_end_frame: true means the model supports start/end-frame generation. supports_video_multimodal_reference: true means the model supports multimodal reference asset lists.
curl -X POST https://silkdock.ai/v1/videos/generations \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-F "model=wan-2.7" \-F "prompt=She slowly turns around" \-F "seconds=5" \-F 'extra_body={"resolution":"1080p","aspect_ratio":"16:9"}' \-F "input_reference=@/path/to/image.jpg"Submit Response
{
"id": "video_xxxxxx",
"object": "video",
"status": "processing",
"usage": {
"duration_seconds": 10.0,
"video_resolution": "1080p",
"has_audio": false
}
}Polling for the Result
Poll GET /v1/videos/{video_id} every few seconds until status is "completed".
# Poll until completedwhile true; doRESULT=$(curl -s https://silkdock.ai/v1/videos/task_abc123 \ -H "Authorization: Bearer $SILKDOCK_API_KEY")STATUS=$(echo $RESULT | jq -r '.status')echo "Status: $STATUS"if [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ]; then echo $RESULT | jq . breakfisleep 5doneasync function pollVideo(videoId) {while (true) { const res = await fetch(`https://silkdock.ai/v1/videos/${videoId}`, { headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}` }, }); const data = await res.json(); console.log("Status:", data.status, "Progress:", data.progress); if (data.status === "completed") return data; if (data.status === "failed") throw new Error(data.error ?? "Generation failed"); await new Promise(r => setTimeout(r, 5000));}}// Full flow: submit then pollconst submit = await fetch("https://silkdock.ai/v1/videos/generations", {method: "POST",headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "seedance-2.0", prompt: "Ocean waves crashing on rocks, sunlight refracting into rainbows", seconds: 10, extra_body: { resolution: "1080p", aspect_ratio: "16:9", },}),});const { id } = await submit.json();const result = await pollVideo(id);console.log("Download:", `https://silkdock.ai/v1/videos/${id}/content`);import requests, os, timeAPI_KEY = os.getenv("SILKDOCK_API_KEY")BASE = "https://silkdock.ai"# Step 1: Submitres = requests.post( f"{BASE}/v1/videos/generations", headers={"Authorization": f"Bearer {API_KEY}"}, json={ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": { "resolution": "1080p", "aspect_ratio": "16:9" }, },)video_id = res.json()["id"]print(f"Task submitted: {video_id}")# Step 2: Pollwhile True: poll = requests.get( f"{BASE}/v1/videos/{video_id}", headers={"Authorization": f"Bearer {API_KEY}"}, ) data = poll.json() print(f"Status: {data['status']} Progress: {data.get('progress', '-')}") if data["status"] == "completed": print(f"Download: {BASE}/v1/videos/{video_id}/content") break if data["status"] == "failed": raise RuntimeError(data.get("error", "Generation failed")) time.sleep(5)package mainimport ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" "time")func main() { apiKey := os.Getenv("SILKDOCK_API_KEY") base := "https://silkdock.ai" // Step 1: Submit body, _ := json.Marshal(map[string]any{ "model": "seedance-2.0", "prompt": "Ocean waves crashing on rocks, sunlight refracting into rainbows", "seconds": 10, "extra_body": map[string]any{ "resolution": "1080p", "aspect_ratio": "16:9", }, }) req, _ := http.NewRequest("POST", base+"/v1/videos/generations", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) raw, _ := io.ReadAll(resp.Body) resp.Body.Close() var submit struct{ VideoID string `json:"id"` } json.Unmarshal(raw, &submit) fmt.Println("Task submitted:", submit.VideoID) // Step 2: Poll for { req, _ = http.NewRequest("GET", base+"/v1/videos/"+submit.VideoID, nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ = http.DefaultClient.Do(req) raw, _ = io.ReadAll(resp.Body) resp.Body.Close() var result struct { Status string `json:"status"` Progress int `json:"progress"` Error string `json:"error"` } json.Unmarshal(raw, &result) fmt.Printf("Status: %s Progress: %d", result.Status, result.Progress) if result.Status == "completed" { fmt.Println("Download:", base+"/v1/videos/"+submit.VideoID+"/content") return } if result.Status == "failed" { fmt.Println("Failed:", result.Error) return } time.Sleep(5 * time.Second) }}Completed Response
{
"id": "video_xxxxxx",
"status": "completed",
"url": "https://cdn.example.com/video.mp4"
}Failed Response
{
"id": "video_xxxxxx",
"status": "failed",
"error": "Content policy violation: prompt was rejected."
}Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique task identifier. Use this to poll status and download the result. |
object | string | Object type, usually "video" on task creation. |
status | string | "processing" | "completed" | "failed" |
url | string | URL of the generated video when status is "completed". |
usage | object | Billing metadata, including duration, resolution, and audio information. |
error | string | Error message when status is "failed". |
Errors
| Scenario | Result |
|---|---|
Unsupported input mode, such as an image-to-video model without input_reference | 400 BadRequestError |
Unsupported resolution and aspect_ratio combination | Falls back to the model default and emits a warning log |
| Task failure | status: "failed" with the reason in error |
| Download before the video is ready | ValueError: video not ready |
Billing
Video generation is billed by model, duration, resolution, and whether audio is included. The usage field contains billing-related metadata, and billing is handled by the gateway.
Additional Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/videos/generations | Submit a video generation task |
GET | /v1/videos/{video_id} | Poll task status |
GET | /v1/videos/{video_id}/content | Download video file (returns video/mp4) |
Download Video
curl "https://silkdock.ai/v1/videos/{video_id}/content" \
-H "Authorization: Bearer $SILKDOCK_API_KEY" \
--output video.mp4Last updated on