SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
7.8 KB

# OpenAI Video API (/v1/videos, Sora 2)

Status: DOCUMENTED + DEPRECATED — the deprecations page (notice 2026-03-24) schedules removal of the Videos API and every Sora 2 model on 2026-09-24. On 2026-09-18 the endpoints still answer: GET /v1/videos, GET /v1/videos/{id}, GET /v1/videos/{id}/content LIVE_VERIFIED; POST /v1/videos, remix, edits, extensions, characters, DELETE DOCUMENTED/UNVERIFIED (not called: cost / destructive). Sources: Videos reference · Video generation guide · Pricing · Deprecations · Changelog (2026-03-12 entries) · model pages sora-2, sora-2-pro · OpenAPI CreateVideo*Body, VideoResource, VideoCharacterResource. Last verified: 2026-09-18. Machine-readable: endpoints fragment openai-images-video-embeddings-moderation.json, parameters/openai-videos.json, objects/openai-media-objects.json, prices/openai-media.json.

# Models

Model Alias → snapshot Output Sizes Price / second (standard · batch) Rate limit (RPM T1…T5) Status
sora-2 (speed, iteration) sora-2 → sora-2-2025-12-08 (older sora-2-2025-10-06) video + synced audio 720×1280, 1280×720 $0.10 · $0.05 25 / 50 / 125 / 200 / 375 DEPRECATED → 2026-09-24
sora-2-pro (production) sora-2-pro → sora-2-pro-2025-10-06 video + audio 720p $0.30 · $0.15; 1024×1792 / 1792×1024 $0.50 · $0.25; 1080×1920 / 1920×1080 $0.70 · $0.35 10 / 25 / 50 / 75 / 150 DEPRECATED → 2026-09-24

Both models accept 4, 8, 12 s (spec enum) and, per guide/changelog 2026-03-12, 16 and 20 s. Cost = seconds × per-second rate (an 8 s 720p sora-2 clip ≈ $0.80).

# Operations

Method / path Body Returns Status
POST /v1/videos JSON or multipart: prompt*, model, seconds, size, input_reference, characters[] (guide only) Video job (status: queued) DOCUMENTED, UNVERIFIED
GET /v1/videos?limit&after&order — {object: list, data: Video[], first_id, last_id, has_more} LIVE_VERIFIED (200)
GET /v1/videos/{video_id} — Video LIVE_VERIFIED (200; unknown id → 404 Video with id '…' not found.)
DELETE /v1/videos/{video_id} — {id, deleted: true, object: "video.deleted"} DOCUMENTED (destructive, not run)
`GET /v1/videos/{video_id}/content?variant=video thumbnail spritesheet` —
POST /v1/videos/{video_id}/remix {prompt} Video (remixed_from_video_id) DOCUMENTED; being replaced by edits (changelog 2026-03-12: deprecated in 6 months)
POST /v1/videos/edits JSON {video: {id}, prompt} or multipart video=@file, model, prompt Video DOCUMENTED, UNVERIFIED (upload path = eligible customers only)
POST /v1/videos/extensions {video: {id}, prompt, seconds} (JSON or multipart) Video (seconds = stitched total) DOCUMENTED, UNVERIFIED
POST /v1/videos/characters multipart video=@clip.mp4;type=video/mp4, name (1–80) {id, name, created_at} DOCUMENTED, UNVERIFIED
GET /v1/videos/characters/{character_id} — {id, name, created_at} DOCUMENTED, UNVERIFIED

There is no list-characters operation: GET /v1/videos/characters?limit=1 → 400 invalid_value "Invalid 'video_id': 'characters'. Expected an ID that begins with 'video'." (routed as /videos/{video_id}).

SDKs: Python client.videos.create | retrieve | list | delete | download_content | remix | edit | extend | create_character | get_character | create_and_poll | poll; Node client.videos.create | retrieve | list | delete | downloadContent | remix | edit | extend | createCharacter | getCharacter.

# Parameters of POST /v1/videos

Param Type Default Notes
prompt * string 1–32 000 — describe shot type, subject, action, setting, lighting
model sora-2 | sora-2-pro | snapshots sora-2
seconds string `"4" "8" "12"(+"16"
size 720x1280 | 1280x720 | 1024x1792 | 1792x1024 (+ 1080x1920 | 1920x1080 sora-2-pro, guide/pricing) 720x1280 spec enum lacks 1080p
input_reference multipart file or JSON {file_id} / {image_url} (URL or data URL ≤ 20 MiB) — becomes the first frame; human faces rejected; Batch: JSON only
characters [{id}], ≤ 2 — guide only, absent from OpenAPI; name must appear verbatim in prompt; not with extensions

# Job lifecycle

text
POST /v1/videos ──► {status:"queued", progress:0}
        │ poll GET /v1/videos/{id} every 10–20 s (exp. backoff)   or   webhook video.completed / video.failed
        ▼
   in_progress (progress %) ──► completed (completed_at, expires_at) ──► GET …/content (mp4 | thumbnail | spritesheet)
                            └──► failed (error{code,message,misalignment?})
  • A render "may take several minutes"; longer/1080p jobs take materially longer.
  • expires_at marks asset expiry: live job had expires_at − completed_at = 172 800 s = 48 h; batch-generated videos downloadable ≤ 24 h after the batch completes. Metadata stays listable after expiry (our 2-month-old job still lists as completed).
  • Webhook payload: {"id":"evt_…","object":"event","created_at":…,"type":"video.completed"|"video.failed","data":{"id":"video_…"}} — id only, fetch details afterwards.
  • Batch API: POST /v1/videos only, JSON bodies, terminal states completed|failed|expired.

# Video object (live sample)

json
{"id":"video_6a5e…a57a","object":"video","created_at":1784590069,"status":"completed","completed_at":1784590117,
 "expires_at":1784762917,"model":"sora-2","progress":100,"prompt":"A simple blue geometric cube rotating on a white background.",
 "remixed_from_video_id":null,"edited_from_video_id":null,"extended_from_video_id":null,"error":null,"seconds":"4","size":"720x1280"}

edited_from_video_id and extended_from_video_id are LIVE_DISCOVERED (absent from reference and spec). error.misalignment{error_type, detailed_explanation, steer.message} reuses the safety-alert error types (see docs/openai/safety.md).

# Remix, edit, extend, characters

  • Remix (/{id}/remix): re-render a completed video with a new prompt; superseded by edits.
  • Edits (/videos/edits): targeted change keeping structure/continuity; one clear adjustment per edit; source = generated video id (model inferred) or uploaded MP4 (+ explicit model, eligible customers).
  • Extensions (/videos/extensions): continue a completed clip using the whole source as context; each extension adds ≤ 20 s; ≤ 6 extensions, ≤ 120 s total; no characters / image references.
  • Characters: reusable non-human subject from a 2–4 s MP4 (16:9 or 9:16, 720p–1080p, match output aspect ratio); ≤ 2 per video; combinable with input_reference; human likeness blocked by default (sales/eligibility).

# Content policy and restrictions (guide)

Under-18-suitable content only (bypass "available in the future"); copyrighted characters/music rejected; real people incl. public figures cannot be generated; input images with human faces rejected; human-likeness character uploads blocked by default.

# Examples and tests

examples/openai/video/ — list.sh|py|ts (LIVE_VERIFIED), create_poll_download.py|ts|sh (UNVERIFIED create; poll + download logic follows the guide). tests/openai/test_video.py: list/retrieve/404 shape unmarked (free); creation behind RUN_VIDEO_TESTS.