Skip to content
Get API key
View as Markdown

Videos

Generates a video from a prompt in the OpenAI Videos format. Videos take minutes, so they run as tasks: create the task, poll it, and download the file when it completes. Paid video models from providers are priced per second of video; see freetheai.org/models.

POSThttps://api.freetheai.org/v1/videos

Create the task ​

bash
curl https://api.freetheai.org/v1/videos \
  -H "Authorization: Bearer $FTAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "MODEL_ID", "prompt": "Waves rolling onto a beach at sunset", "seconds": 8}'
python
import os, time
import requests

base = "https://api.freetheai.org/v1"
headers = {"Authorization": f"Bearer {os.environ['FTAI_KEY']}"}

task = requests.post(f"{base}/videos", headers=headers,
                     json={"model": "MODEL_ID", "prompt": "Waves rolling onto a beach at sunset", "seconds": 8}).json()
while task["status"] in ("queued", "in_progress"):
    time.sleep(10)
    task = requests.get(f"{base}/videos/{task['id']}", headers=headers).json()

if task["status"] == "completed":
    video = requests.get(f"{base}/videos/{task['id']}/content", headers=headers)
    open("video.mp4", "wb").write(video.content)
ts
import { writeFile } from 'node:fs/promises'

const base = 'https://api.freetheai.org/v1'
const headers = { 'Authorization': `Bearer ${process.env.FTAI_KEY}`, 'Content-Type': 'application/json' }

let task = await (await fetch(`${base}/videos`, {
  method: 'POST', headers, body: JSON.stringify({ model: 'MODEL_ID', prompt: 'Waves rolling onto a beach at sunset', seconds: 8 }),
})).json()
while (task.status === 'queued' || task.status === 'in_progress') {
  await new Promise(resolve => setTimeout(resolve, 10000))
  task = await (await fetch(`${base}/videos/${task.id}`, { headers })).json()
}
if (task.status === 'completed') {
  const video = await fetch(`${base}/videos/${task.id}/content`, { headers })
  await writeFile('video.mp4', Buffer.from(await video.arrayBuffer()))
}
FieldTypeDescription
modelstringA video model ID from GET /v1/models ("type": "video").
promptstringWhat to show.
secondsintegerOptional. Length of the video (for example 4, 8, or 12); 4 when left out.
sizestringOptional. For example 1280x720, when the model supports it.

The create call answers at once with the task ("object": "video", "status": "queued", and a poll_url).

Get the video ​

Poll GET /v1/videos/{id} every 10 seconds or so. status moves from queued to in_progress to completed or failed; progress counts to 100. A completed task carries content_url; download the MP4 from GET /v1/videos/{id}/content. A failed one carries error with a code and a message.

The request holds the price of the seconds you ask for. You are charged for the seconds delivered, never more than you asked for; a failed or expired task costs nothing.

Errors ​

StatusMeaning
400A field has a value the endpoint does not take (the message names it).
401Missing or invalid API key.
402Not enough wallet balance, or the key's budget is used (paid usage errors).
404No model has that ID, none of the providers you follow serve it, or the task ID is not yours.
503The provider is busy. Retry; nothing is charged.