VEO 3.1 Fast HD API
Find VEO 3.1 Fast HD model IDs, request examples, and current availability on ModelPort.
Model details and pricing
Upload reference files
Call GET /v1/models with your key and check available before submitting.
Request parameters
| Parameter | Accepted values | Default |
|---|---|---|
duration | 4, 6, 8 | 8 |
resolution | 720p | 720p |
aspect_ratio | 16:9, 9:16 | 16:9 |
generate_audio | false, true | true |
n | 1 | 1 |
Reference files
| Input mode | Roles and allowed counts |
|---|---|
| image | first_frame (1–1), last_frame (0–1) |
Quote and submit
Set MODELPORT_API_KEY. The cURL example uses Bash and jq, Python uses its standard library, and Node.js uses a .mjs file. These examples submit a job after retrieving a quote.
cURL (Bash)
cURL (Bash)
set -eu
: "${MODELPORT_API_KEY:?Set MODELPORT_API_KEY}"
base='https://api.apimodel.store'
request='{"model":"veo-3.1-fast-hd","prompt":"A low camera moves along a misty river.","parameters":{"duration":8,"resolution":"720p","aspect_ratio":"16:9","generate_audio":true,"n":1}}'
request_id=${MODELPORT_REQUEST_ID:-modelport-example-$(date +%s)-$$}
quote=$(curl --fail-with-body --max-time 45 -sS 'https://api.apimodel.store/v1/quotes' \
-H "Authorization: Bearer $MODELPORT_API_KEY" \
-H "Content-Type: application/json" --data "$request")
quoted_cap=$(printf '%s' "$quote" | jq -er '.billing_price_usd | strings')
cap=${MODELPORT_MAX_PRICE_USD:-$quoted_cap}
printf 'Request ID: %s, maximum charge: %s USD\n' "$request_id" "$cap" >&2
payload=$(printf '%s' "$request" | jq -ce --arg cap "$cap" '. + {max_price_usd: $cap}')
job=$(curl --fail-with-body --max-time 45 -sS "$base/v1/jobs" \
-H "Authorization: Bearer $MODELPORT_API_KEY" -H "Idempotency-Key: $request_id" \
-H "Content-Type: application/json" --data "$payload")
job_id=$(printf '%s' "$job" | jq -er '.id | strings')
printf 'Job ID: %s\n' "$job_id" >&2
attempt=0
while [ "$attempt" -lt 90 ]; do
status=$(printf '%s' "$job" | jq -er '.status')
case "$status" in succeeded|failed) break ;; esac
sleep 2
job=$(curl --fail-with-body --max-time 45 -sS "$base/v1/jobs/$job_id" -H "Authorization: Bearer $MODELPORT_API_KEY")
attempt=$((attempt + 1))
done
printf '%s\n' "$job"Python
Python
import json
import os
import time
import uuid
from urllib.request import Request, urlopen
BASE = "https://api.apimodel.store"
KEY = os.environ["MODELPORT_API_KEY"]
request_id = os.getenv("MODELPORT_REQUEST_ID") or str(uuid.uuid4())
payload = json.loads("{\"model\":\"veo-3.1-fast-hd\",\"prompt\":\"A low camera moves along a misty river.\",\"parameters\":{\"duration\":8,\"resolution\":\"720p\",\"aspect_ratio\":\"16:9\",\"generate_audio\":true,\"n\":1}}")
def api(path, data=None, request_key=None):
headers = {"Authorization": f"Bearer {KEY}"}
if data is not None:
headers["Content-Type"] = "application/json"
if request_key:
headers["Idempotency-Key"] = request_key
body = json.dumps(data).encode("utf-8") if data is not None else None
with urlopen(Request(BASE + path, data=body, headers=headers), timeout=45) as response:
return json.load(response)
quote = api("/v1/quotes", payload)
cap = os.getenv("MODELPORT_MAX_PRICE_USD") or quote["billing_price_usd"]
print(f"Request ID: {request_id}, maximum charge: {cap} USD", flush=True)
job = api("/v1/jobs", {**payload, "max_price_usd": cap}, request_id)
job_id = job["id"]
print("Job ID:", job_id, flush=True)
for _ in range(90):
if job["status"] in ("succeeded", "failed"):
break
time.sleep(2)
job = api(f"/v1/jobs/{job_id}")
print(json.dumps(job, indent=2, ensure_ascii=False))Node.js
Node.js
import { randomUUID } from "node:crypto";
import { setTimeout as sleep } from "node:timers/promises";
const base = "https://api.apimodel.store";
const key = process.env.MODELPORT_API_KEY;
if (!key) throw new Error("Set MODELPORT_API_KEY");
const requestId = process.env.MODELPORT_REQUEST_ID || randomUUID();
const payload = {
"model": "veo-3.1-fast-hd",
"prompt": "A low camera moves along a misty river.",
"parameters": {
"duration": 8,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true,
"n": 1
}
};
async function api(path, data, requestKey) {
const headers = { Authorization: `Bearer ${key}` };
if (data) headers["Content-Type"] = "application/json";
if (requestKey) headers["Idempotency-Key"] = requestKey;
const response = await fetch(base + path, {
method: data ? "POST" : "GET", headers,
body: data && JSON.stringify(data), signal: AbortSignal.timeout(45_000),
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
return response.json();
}
const quote = await api("/v1/quotes", payload);
const cap = process.env.MODELPORT_MAX_PRICE_USD || quote.billing_price_usd;
console.log(`Request ID: ${requestId}, maximum charge: ${cap} USD`);
let job = await api("/v1/jobs", { ...payload, max_price_usd: cap }, requestId);
const jobId = job.id;
console.log("Job ID:", jobId);
for (let attempt = 0; attempt < 90 && !["succeeded", "failed"].includes(job.status); attempt++) {
await sleep(2_000);
job = await api(`/v1/jobs/${jobId}`);
}
console.log(JSON.stringify(job, null, 2));To retry the same submission, keep the payload and set MODELPORT_REQUEST_ID and MODELPORT_MAX_PRICE_USD to the values printed on the first run.
Use the quote to set max_price_usd on the same request to POST /v1/jobs.