Video generation API
Video quotes, reviewed reference images, asynchronous operations and authorized MP4 delivery.
Project video API
Use a project key that your company membership and role permit you to execute. The company owner is the billing owner; the employee remains the requesting actor. Project/group restrictions and current key access apply to every method. Neither company membership nor a company-administrator role automatically opens another employee’s private video history. Domain/IP policy also applies. The API host in these examples is https://api.b2b-llm.com; use the enabled host of your current service profile or custom domain instead when applicable. Do not use a temporary browser permission as a CLI key.
Methods
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/videos | Create one video intent |
| POST | /v1/videos/quote | Validate settings and obtain a nonpaid quote |
| GET | /v1/videos/catalog | Available video offers for a model |
| GET | /v1/videos/operations | Scoped history or idempotency lookup |
| GET | /v1/videos/operations/{id} | Compact state and result links; accounting via ?view=details |
| GET | /v1/videos/operations/{id}/result | Saved result manifest, not video bytes |
| GET | /v1/videos/operations/{id}/content | Private MP4 bytes; Range supported |
These are the service's dedicated video methods. Create and quote accept JSON, not the supplier's multipart interface. This is a bounded text/image-to-video workflow, not a general-purpose video SDK passthrough. A protocol/model name does not guarantee current availability; select an offer currently returned for your key. Reviewed reference images are described below. Remix, editing, cancellation, synchronous video responses and generation through generic Async/Batch are not supported here.
Request and quote
Required fields: model and a nonblank prompt. seconds is a decimal integer string. Depending on the offer, output settings are either a supported size (WIDTHxHEIGHT) or resolution plus aspect_ratio; do not mix these forms. Omitted settings use that offer's explicit defaults. Its catalog request fields, including request.prompt_max_chars, define what is accepted. Unsupported settings, duplicate JSON keys, unknown fields, binary/multipart input and an oversized JSON body are rejected. The JSON body limit is12MiB including base64 inputs; your service profile can be stricter. Read max_request_bytes in the catalog.
Optional model_gate: route_id identifies a returned offer; async can only be true (this operation is always asynchronous); quote_sha256 is the64-hex fingerprint from the price check. False async is not a request to wait indefinitely.
Send the same settings to POST /v1/videos/quote. It returns route_id, model, quote, quote_sha256, charged:false and provider_health_verified:false. It creates no generation, debit or reservation. Prices use the disclosed price per completed video or duration from the validated completion reply, with current applicable coefficients. File size is not a price input. Refreshing a quote never submits a paid request.
For explicit price confirmation, retain the returned fingerprint in the create request. Playground does not send max_cost_usd. Changed price context is rejected as video_quote_changed. Runtime capacity and eventual supplier success are not reserved by a quote.
# A paid action: choose model and settings that your catalog actually offers.
curl --fail-with-body 'https://api.b2b-llm.com/v1/videos' \
-H "Authorization: Bearer $MODEL_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: my-video-0001' \
--data '{"model":"YOUR_ALLOWED_VIDEO_MODEL","prompt":"A small paper boat on still water","seconds":"4","size":"1280x720","model_gate":{"async":true}}'
The duration and dimensions above are illustrative, not a universal model guarantee. Copying does not run the command. Executing it may incur a charge. Do not add an automatic --retry around a paid create.
Identity and lifecycle
Creation requires one Idempotency-Key:1–128 printable non-space ASCII characters. The same key and validated unchanged intent returns the existing operation; changed intent returns409. Model, prompt, normalized settings, explicit route and price conditions participate in identity. Keep the same key and actor context; using a new key or intent is not a safe retry of an unknown paid outcome. Records survive file expiry.
Accepted create returnsHTTP202, a Location and local operation ID. Replaying an already completed intent can return200 with the same operation, not a new movie. Check status: HTTP200 on a read or202 on queue acceptance does not mean the supplier finished.
States progress through queued, preparing, dispatching, received, polling, retrieving and completed. Some fast stages may not be observed. provider_progress is omitted when unavailable, otherwise the supplier-reported percentage; it is not an ETA. The explicit details view can include supplier_http_status and last_poll_http_status; these are not part of the compact default. Closing the page does not cancel an accepted operation.
There is no automatic paid retry after an ambiguous create. outcome_unknown requires Support; review_required means saved evidence needs review; retrieval_failed means an already generated result could not be obtained or verified. A failed download is not permission to generate again. Bounded checks may stop with video_poll_deadline; they do not guarantee the supplier stopped its work. Report the operation ID and safe code rather than sending a duplicate.
History, MP4 and access
GET /v1/videos/operations returns up to50 scoped entries with next_cursor; pass it as before for older entries. ?idempotency_key=... performs a read-only lookup and returns submission_found. Momentary absence is not evidence that an in-flight create did nothing.
A completed detail/result contains a file descriptor with MIME, bytes, SHA-256, dimensions and duration. /result is a JSON manifest. /content is the actual private video/mp4, supports authorized Range reads and ?download=1, and never generates a new movie. Every read requires current authorization. The completed format is MP4 with H264 video and optional AAC audio; supported offers are bounded to30seconds,4096pixels per dimension and128MiB, and may be stricter. Files normally expire24hours after creation. Missing, expired or corrupt content is not regenerated by reading it.
An operation may have a recorded price even when later file retrieval failed. In the explicit details view, accounting_recorded means an accounting input exists, not a completed wallet debit. The settlement observation separates pending, settled/recovered, unavailable and retained-record absence. Only an actual observed settled/recovered positive amount is labelled Debited; Usage Limit and wallet money are distinct. Historical result/settlement rows may no longer be available. Reading a paid result does not require a positive current balance, but current rights remain mandatory.
Errors and inspection
Typical input problems:400 invalid fields/idempotency,403 revoked scope or changed grant body,409 idempotency conflict,413 JSON too large,415 wrong Content-Type,422 unsupported settings or changed quote,429 capacity/limits,503 unavailable catalog/service. Inspect the safe error.code rather than assuming every503 means no work. For an operation, a nonempty error_code accompanies its durable state and may represent a supplier failure even though the state GET returned200.
Playground Raw response shows the service response it actually received, including errors and whitespace, not secret supplier headers. Raw data must remain private. Sharing a prompt, credential or downloaded response publicly is not required for Support to locate an operation.
Project video output parameters
A project key may expose routes that accept resolution and aspect_ratio instead of size. Read the selected route in GET /v1/videos/catalog; do not combine these fields with size. seconds remains a string in this API. The catalog provides the allowed values and defaults. Unsupported input images or references are rejected rather than silently omitted.
{"model":"YOUR_AVAILABLE_VIDEO_MODEL","prompt":"A paper boat on a quiet lake","seconds":"6","resolution":"720p","aspect_ratio":"16:9","model_gate":{"async":true}}
Send this body to your workspace API's POST /v1/videos with the permitted project key and one retained Idempotency-Key. Quote the same parameters with POST /v1/videos/quote first; changing them invalidates the previous quote. A compatible route may allow 1–15 seconds and 480p/720p, but the selected catalog, not this example, defines the permitted project options. The result remains the authorized saved MP4; third-party result URLs are not public client download links.
Compact status and accounting details
Since version11.0.0, operation responses are compact by default: object, id, model, status, created, status_url, result_url. An actionable error_code or reported progress is included only when present. Completed results include availability, expiry and required file descriptors. Empty fields, quote, normalized usage, settlement and supplier diagnostics are omitted. Omission does not mean zero cost or a completed debit.
Use GET /v1/videos/operations/{id}?view=details for the previous full authorized accounting view. Lists and result manifests also support the explicit details view where applicable. Reading details never generates new media or expands access. The quote endpoint remains the separate place to inspect an uncharged price calculation.
Optional reference inputs
Read the selected offer's request.reference_images object first. Its modes, max_images, mime_types, max_image_bytes, max_total_bytes and max_pixels are binding limits. No object means text-only. Use image for one first frame, or reference_images for a set, never both. Only inline PNG/JPEG/WebP data URLs are accepted; external input URLs and file IDs are not accepted. The server verifies actual raster content. Some first-frame offers require exactly the selected output dimensions.
{"model":"YOUR_ALLOWED_VIDEO_MODEL","prompt":"A calm scene","seconds":"6","resolution":"720p","aspect_ratio":"16:9","image":{"url":"data:image/png;base64,REPLACE_WITH_IMAGE_BYTES"},"model_gate":{"route_id":"YOUR_OFFERED_ROUTE","async":true,"quote_sha256":"YOUR_QUOTE_FINGERPRINT"}}
For a supported reference set, replace image with "reference_images":[{"url":"data:image/png;base64,..."},{"url":"data:image/jpeg;base64,..."}]. The examples are not executable with placeholders. Quote the exact same inputs/settings first and retain the fingerprint and one Idempotency-Key for creation. Different input modes can have different rates; a model name alone does not enable reference support.
Read a result: Raw and cURL
Use the same active company key and employee/actor context that created the operation. A shared project key, company ownership or access to company billing does not grant another employee's result. Current membership and project/key permissions are checked again. Get OPERATION_ID from the accepted creation response or your authorized history, and set MODEL_API_KEY locally without publishing the secret. A temporary Playground permission is not a reusable CLI credential; copying a command does not export or enlarge that permission.
GET https://api.b2b-llm.com/v1/videos/operations/{id}/result
Authorization: Bearer <YOUR_API_KEY>
# status
curl --fail-with-body --request GET \
--url "https://api.b2b-llm.com/v1/videos/operations/${OPERATION_ID:?Set OPERATION_ID}" \
--header "Authorization: Bearer ${MODEL_API_KEY:?Set MODEL_API_KEY}" \
--output video-status.json
# result
curl --fail-with-body --request GET \
--url "https://api.b2b-llm.com/v1/videos/operations/${OPERATION_ID:?Set OPERATION_ID}/result" \
--header "Authorization: Bearer ${MODEL_API_KEY:?Set MODEL_API_KEY}" \
--output video-result.json
# MP4
curl --fail-with-body --request GET \
--url "https://api.b2b-llm.com/v1/videos/operations/${OPERATION_ID:?Set OPERATION_ID}/content" \
--header "Authorization: Bearer ${MODEL_API_KEY:?Set MODEL_API_KEY}" \
--output video.mp4
/result is a JSON manifest. To save the actual movie, use /content and an .mp4 filename. Saving the manifest as .mp4 does not turn it into a video. The local operation ID is the ID from this API, not a supplier task ID.
These are bodyless GET requests: no Content-Type, Idempotency-Key, quote, route_id or max_cost_usd is needed. Read status until it reports completion, then read the result/file. Pending, failed, expired and unauthorized responses are not output files; --fail-with-body returns a nonzero exit status for HTTP errors but may still write their body to the output filename. Check the status and content type before treating a downloaded body as media. Do not repeat a paid POST because a GET failed.
Playground's Get the result · Raw / cURL block generates these commands for the selected operation and its original key. They are examples of a new read, not a recording of an earlier HTTP exchange. Copying or switching command tabs makes no network request. Opening history or a saved result still performs its normal authorized read; it does not generate, reserve or charge again.