curl
bash
export GENSTA_API_KEY="your-secret-key"
curl --silent --show-error --fail-with-body \
-X POST "https://api-platform.gensta.ai/v1/generations" \
-H "Authorization: Bearer $GENSTA_API_KEY" \
-H "Idempotency-Key: order-8493-shot-1" \
-H "Content-Type: application/json" \
-d '{
"model": "wan-3.0",
"mode": "text_to_video",
"variant": "standard",
"parameters": {
"resolution": "720p",
"duration_seconds": 5,
"ratio": "16:9",
"audio": true,
"prompt_extend": true
},
"input": {
"prompt": "A quiet lake at sunrise, cinematic aerial shot"
}
}'TypeScript
typescript
import { randomUUID } from "node:crypto";
interface Generation {
id: string;
status: string;
artifacts: Array<{ download_url: string }>;
error: { code: string; message: string } | null;
}
const baseUrl = "https://api-platform.gensta.ai/v1";
const apiKey = process.env.GENSTA_API_KEY;
if (!apiKey) throw new Error("GENSTA_API_KEY is required");
const headers = {
Authorization: "Bearer " + apiKey,
"Content-Type": "application/json",
};
const create = await fetch(baseUrl + "/generations", {
method: "POST",
headers: { ...headers, "Idempotency-Key": randomUUID() },
body: JSON.stringify({
model: "wan-3.0",
mode: "text_to_video",
variant: "standard",
parameters: {
resolution: "720p",
duration_seconds: 5,
ratio: "16:9",
audio: true,
prompt_extend: true,
watermark: false,
},
input: { prompt: "A paper boat crosses a rain puddle" },
}),
});
if (!create.ok) throw new Error(await create.text());
const generation = (await create.json()) as Pick<Generation, "id">;
while (true) {
await new Promise((resolve) => setTimeout(resolve, 10_000));
const response = await fetch(
baseUrl + "/generations/" + generation.id,
{ headers: { Authorization: "Bearer " + apiKey } },
);
if (!response.ok) throw new Error(await response.text());
const current = (await response.json()) as Generation;
if (current.status === "succeeded") {
console.log(current.artifacts[0]?.download_url);
break;
}
if (["failed", "canceled"].includes(current.status)) {
throw new Error(current.error?.message || current.status);
}
if (["submission_unknown", "billing_reconciliation"].includes(current.status)) {
console.warn("Operator review required", current.id, current.status);
}
}Python
python
import json
import os
import time
import uuid
from urllib.request import Request, urlopen
BASE_URL = "https://api-platform.gensta.ai/v1"
API_KEY = os.environ["GENSTA_API_KEY"]
payload = {
"model": "wan-3.0",
"mode": "text_to_video",
"variant": "standard",
"parameters": {
"resolution": "720p",
"duration_seconds": 5,
"ratio": "16:9",
"audio": True,
"prompt_extend": True,
"watermark": False,
},
"input": {"prompt": "A paper boat crosses a rain puddle"},
}
request = Request(
BASE_URL + "/generations",
data=json.dumps(payload).encode(),
method="POST",
headers={
"Authorization": "Bearer " + API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
)
with urlopen(request) as response:
generation = json.load(response)
while True:
time.sleep(10)
request = Request(
BASE_URL + "/generations/" + generation["id"],
headers={"Authorization": "Bearer " + API_KEY},
)
with urlopen(request) as response:
current = json.load(response)
if current["status"] == "succeeded":
print(current["artifacts"][0]["download_url"])
break
if current["status"] in {"failed", "canceled"}:
raise RuntimeError(current.get("error") or current["status"])
if current["status"] in {"submission_unknown", "billing_reconciliation"}:
print("Operator review required:", current["id"], current["status"])
Production clients should add exponential backoff and jitter for retryable GET failures, persist the generation ID, and use application-level timeouts without creating replacement jobs.