Skip to content
GetAPI
English
Menu

GetAPI.ONE

Generate video with the ONE task API

Submit an OpenAI-shaped video task, preserve its public task ID, poll the exact ONE status route to a terminal state, and fetch content only after completion.

Confirm the protocol before spending

  • Choose a current catalog model that explicitly declares the OpenAI video endpoint.
  • Review live pricing and the model’s supported input fields; video work may be asynchronous and billable.
  • Use a short, low-risk prompt for the first accepted test.
text
POST https://www.getapi.one/v1/videos
GET https://www.getapi.one/v1/videos/{task_id}
GET https://www.getapi.one/v1/videos/{task_id}/content

Submit, poll, and fetch

  1. Submit POST https://www.getapi.one/v1/videos and save the returned task ID exactly.
  2. Poll GET https://www.getapi.one/v1/videos/{task_id} at a fixed interval with a bounded number of checks; do not create a new task while waiting.
  3. Continue for queued or in_progress; stop successfully only for completed.
  4. Stop and surface the error for failed. Treat unknown states as non-success and preserve the response for diagnosis.
  5. After completed, fetch GET https://www.getapi.one/v1/videos/{task_id}/content.
  6. Stream the content in fixed-size chunks under a cumulative limit. The example uses a 512 MiB local ceiling and removes its partial file on any read, validation, write, or cancellation failure.
Submit the task
curl --fail-with-body https://www.getapi.one/v1/videos \
  -H "Authorization: Bearer $GETAPI_ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<OPENAI_VIDEO_MODEL_ID_FROM_CURRENT_CATALOG>",
    "prompt": "A five-second locked-camera product turntable on a neutral background"
  }' > video-submit.json
Poll at most 30 times, then fetch only after completed
import json
import os
import time
from pathlib import Path
from urllib.parse import quote
from urllib.request import Request, urlopen

base_url = "https://www.getapi.one"
api_key = os.environ["GETAPI_ONE_API_KEY"]
submitted = json.loads(Path("video-submit.json").read_text(encoding="utf-8"))
task_id = submitted.get("id") or submitted.get("task_id")
if not task_id:
    raise ValueError("Submit response did not contain id or task_id")

safe_id = quote(task_id, safe="")
headers = {"Authorization": f"Bearer {api_key}"}
for attempt in range(30):
    request = Request(f"{base_url}/v1/videos/{safe_id}", headers=headers)
    with urlopen(request, timeout=30) as response:
        task = json.load(response)
    status = task.get("status")
    if status == "completed":
        break
    if status == "failed":
        raise RuntimeError(f"video task failed: {task.get('error')}")
    if status not in {"queued", "in_progress"}:
        raise RuntimeError(f"unknown non-success status: {status}")
    if attempt == 29:
        raise TimeoutError("video was not complete after 30 status checks")
    time.sleep(10)

content_request = Request(
    f"{base_url}/v1/videos/{safe_id}/content",
    headers=headers,
)
MAX_VIDEO_BYTES = 512 * 1024 * 1024
CHUNK_BYTES = 1024 * 1024
output_path = Path("result.mp4")
created_output = False
with urlopen(content_request, timeout=60) as response:
    content_type = response.headers.get_content_type()
    if not content_type.startswith("video/"):
        raise ValueError(f"unexpected content type: {content_type}")
    try:
        output = output_path.open("xb")
        created_output = True
        with output:
            total_bytes = 0
            while chunk := response.read(CHUNK_BYTES):
                total_bytes += len(chunk)
                if total_bytes > MAX_VIDEO_BYTES:
                    raise ValueError("video exceeds the local 512 MiB limit")
                output.write(chunk)
    except BaseException:
        if created_output:
            output_path.unlink(missing_ok=True)
        raise

Implement the state machine

StatusClient action
queuedWait for the fixed interval, then query the same task ID within the bounded number of checks.
in_progressShow progress if supplied and keep polling.
completedStop polling and request the content route.
failedStop polling, record the safe error details, and require an intentional retry.

Verify the expected result

  • The submit response provides a task ID and the client stores it durably enough for the workflow.
  • Every status request uses that same ID and never creates duplicate work.
  • The downloaded content has a video content type and opens only after completed.

Recover without duplicating tasks

  • On submit timeout, do not blindly submit again: inspect whether a task ID or console record was created.
  • On 404 while polling, verify the public task ID, the exact singular/plural route, and the same account key.
  • On failed, preserve the model, safe request summary, task ID, and error details before changing inputs.

Protect media tasks and results

  • Keep the key and task lookup on your authenticated backend.
  • Validate prompts, uploads, duration, dimensions, and counts against the selected model contract before forwarding.
  • Store approved results in controlled storage; do not assume a content URL is permanent or public-safe.
  • Set a cumulative download limit below your memory and storage budget, stream fixed-size chunks, and clean partial artifacts when the download does not finish.

Next steps