Query Kling Task
curl --request GET \
--url https://api.mixroute.ai/kling/tasksimport requests
url = "https://api.mixroute.ai/kling/tasks"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.mixroute.ai/kling/tasks', 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://api.mixroute.ai/kling/tasks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mixroute.ai/kling/tasks"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.mixroute.ai/kling/tasks")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixroute.ai/kling/tasks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyKling
Query Kling Task
Query Kling gateway task states, video outputs and failure reasons.
Query Kling Task
curl --request GET \
--url https://api.mixroute.ai/kling/tasksimport requests
url = "https://api.mixroute.ai/kling/tasks"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.mixroute.ai/kling/tasks', 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://api.mixroute.ai/kling/tasks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mixroute.ai/kling/tasks"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.mixroute.ai/kling/tasks")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixroute.ai/kling/tasks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyAll four Kling generation endpoints share this query endpoint. Use
Poll about every 15 seconds and back off on rate limits or transient network errors. Responses contain the latest state obtained by the gateway and may lag by a few seconds. A client wait timeout is not a server task failure; keep the ID and continue querying rather than creating a replacement task.
Check both HTTP status and JSON code. A [gateway] message prefix identifies gateway rejections, such as a model/endpoint mismatch, empty prompt or batch query. Upstream rejections retain upstream error details and request IDs. Keep request_id and the task ID for troubleshooting.
Result URLs point to third-party media and may use expiring signatures or retention limits. Save successful outputs promptly rather than treating their URLs as permanent storage. Do not download them with the authenticated session or append your API Key to the URL.
data.id from the submission response.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
task_ids | string | Yes | One MixRoute gateway task ID, such as task_example. Despite the plural name, only one ID is allowed; comma-separated batches are unsupported. |
external_task_ids is unsupported. Upstream IDs, callback IDs and custom external_task_id values cannot replace the gateway task ID.
curl --get "https://api.mixroute.ai/kling/tasks" \
--header "Authorization: Bearer $MIXROUTE_API_KEY" \
--data-urlencode "task_ids=$KLING_TASK_ID"
Response
{
"code": 0,
"message": "",
"data": [
{
"id": "task_example",
"status": "succeeded",
"outputs": [
{
"type": "video",
"url": "https://example.com/generated.mp4",
"duration": "5.041"
}
]
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
code | integer | Yes | 0 means the query request succeeded, not that generation completed. Upstream business errors may use HTTP 200 with nonzero code. |
request_id | string | No | Identifier for troubleshooting this HTTP request, distinct from the task ID; retain it when present. |
data | object[] | Yes | Array of query results; select the task matching your id. |
data[].id | string | Yes | Gateway task ID. |
data[].status | string | Yes | submitted, processing, succeeded or failed, as determined by the gateway. |
data[].message | string | No | Task failure reason, distinct from the outer request message. |
data[].outputs | object[] | No | Video outputs on success. Read url from type=video entries; may also contain id, watermark_url and duration. |
data[].outputs[].duration | string / number | No | Actual generated seconds, potentially fractional; do not truncate to an integer. |
data[].billing | object[] | No | Optional upstream billing information, not guaranteed and not proof of final MixRoute charges. |
data[].create_time / update_time | integer | No | Upstream Unix timestamps in milliseconds, when present. |
data[].external_id | string | No | Custom business identifier forwarded from upstream, when present. |
State Handling
| State | Action |
|---|---|
submitted | Accepted; continue polling. |
processing | Processing; continue polling. |
succeeded | Stop polling and read video URLs. |
failed | Stop polling and inspect message. |
Error Handling
{
"code": 400,
"message": "[gateway] unsupported model on this endpoint",
"request_id": "REQUEST_ID"
}
Complete Python Workflow
Install requests and set MIXROUTE_API_KEY. The first run submits one task; setting KLING_TASK_ID queries an existing task instead. POST is not retried automatically; after a submission timeout, check the console first.import os
import time
from urllib.parse import urlparse
import requests
BASE_URL = "https://api.mixroute.ai/kling"
def parse_response(response):
try:
result = response.json()
except ValueError as exc:
raise RuntimeError(f"HTTP {response.status_code}: invalid JSON response") from exc
if not isinstance(result, dict):
raise RuntimeError(f"HTTP {response.status_code}: expected a JSON object")
code = result.get("code")
if not 200 <= response.status_code < 300 or type(code) is not int or code != 0:
raise RuntimeError(
f"HTTP {response.status_code}; code={code}; "
f"request_id={result.get('request_id', '')}; "
f"message={result.get('message', '')}"
)
return result
def create_video(session):
response = session.post(
BASE_URL + "/text-to-video/kling-3.0",
json={
"prompt": "A ceramic mug slowly rotates on a white tabletop.",
"settings": {"resolution": "720p", "duration": 5,
"aspect_ratio": "16:9", "audio": "off"},
},
timeout=120,
allow_redirects=False,
)
task_id = parse_response(response).get("data", {}).get("id")
if not task_id:
raise RuntimeError("Submission returned no task ID")
return task_id
def wait_for_video(session, task_id, timeout_seconds=1800):
deadline = time.monotonic() + timeout_seconds
delay = 15
while time.monotonic() < deadline:
remaining = deadline - time.monotonic()
if remaining <= 0:
break
try:
response = session.get(
BASE_URL + "/tasks", params={"task_ids": task_id},
timeout=min(30, remaining), allow_redirects=False,
)
except (requests.Timeout, requests.ConnectionError):
delay = min(delay * 2, 60)
else:
if response.status_code in (429, 500, 502, 503, 504):
delay = min(delay * 2, 60)
else:
tasks = parse_response(response).get("data")
if not isinstance(tasks, list):
raise RuntimeError("Invalid task response")
task = next((item for item in tasks if item.get("id") == task_id), None)
if task is None:
raise RuntimeError("Task not found in response")
status = task.get("status")
if status == "succeeded":
videos = [item for item in task.get("outputs", [])
if item.get("type") == "video" and item.get("url")]
if not videos:
raise RuntimeError("Successful task has no video output")
for item in videos:
parsed = urlparse(item["url"])
if parsed.scheme not in ("https", "http") or not parsed.netloc:
raise RuntimeError("Invalid output URL")
return videos
if status == "failed":
raise RuntimeError(task.get("message") or task)
if status not in ("submitted", "processing"):
raise RuntimeError("Unknown task status: " + str(status))
delay = 15
remaining = deadline - time.monotonic()
if remaining > 0:
time.sleep(min(delay, remaining))
raise TimeoutError("Keep task ID and query later: " + task_id)
if __name__ == "__main__":
with requests.Session() as session:
session.headers["Authorization"] = "Bearer " + os.environ["MIXROUTE_API_KEY"]
task_id = os.environ.get("KLING_TASK_ID") or create_video(session)
print("task_id:", task_id, flush=True)
for video in wait_for_video(session, task_id):
print(video["url"], video.get("duration"))