video content blocks are supported in user messages, mirroring
the bytes | s3Location pattern of Bedrock Converse’s
video source. This is the input-side counterpart of
Video generation, which creates video from a
text prompt — don’t confuse the two.
Model support
Video input is available on the Gemini family only. Sending a video block to any other model returns an HTTP 400 before the request reaches the provider (see Limits & errors).Inline video (≤ 20 MB)
For small files, hand the SDK raw bytes — it base64-encodes them into the request for you. Base64 inflates bytes by ~33% against the gateway’s 30 MB request cap, so inline video is capped at 20 MB raw per request (larger inline payloads are rejected with HTTP 413 — use the upload flow below instead). All five SDKs support video input as of SDK v0.3.0.Large videos: upload, then reference by URI
For files over 20 MB (up to 1 GB), upload once and reference the returnedaudacity://files/… URI in as many requests as you like. The
flow has three steps:
POST /v1/fileswithcontent_typeandsize_bytes— returns afile_id, a signedupload_url(valid ~15 minutes), theurito reference in chat requests, andexpires_at.- Upload the bytes to
upload_urlover a resumable session (Google Cloud Storage protocol: one POST opens the session, then PUT the bytes). - Reference the video with
{"video": {"format": …, "source": {"uri": …}}}in aConversecall.
GET /v1/files/{file_id} reports upload status — "pending"
before the bytes land, then "uploaded" with size_bytes and
content_type.
The SDK helpers (client.files.upload in Python/TypeScript,
UploadFile/uploadFile in Go/Java, upload_file() in
Rust) run this whole flow for you and stream the file in 8 MB chunks, automatically
resuming from the last confirmed byte after a network drop. The full loop in Python:
Calling without an SDK? On the raw
OpenAI-protocol endpoint, video rides the A per-part
file
content part — inline as a data URL in file_data, or by reference in
file_id — with the MIME type in format:"detail" field and a request-level
"media_resolution" field control media resolution (next section).Media resolution (video token cost)
Video is tokenized frame by frame on Gemini, so long clips get expensive fast. The request-levelmediaResolution option (wire name:
media_resolution) controls how densely video is sampled —
"low" processes video at roughly 4× fewer tokens. Non-Gemini
models ignore the field; when unset, the model’s default applies.
Raw-protocol callers can also set
detail per content part; an explicit
per-part value wins over the request-level field. On Gemini 2.5 models
the highest resolution across all parts applies to the whole request; true per-part
granularity starts with Gemini 3.
Supported formats
Limits & errors
- Inline cap — 20 MB of raw video per request (all video parts combined). Exceeding it returns 413 with a message pointing to the upload flow.
- Upload cap — 1 GB per file.
POST /v1/filesrejects a largersize_bytes, or an unsupportedcontent_type, with 400. - Upload URL expiry — the signed
upload_urlis valid ~15 minutes; create a fresh slot if it lapses. - File expiry — uploaded files auto-delete after ~24 hours. Referencing an expired or unknown URI fails with 400:
video file "audacity://files/…" not found or expired; upload via POST /v1/files and retry. - Non-video model — sending video to anything outside the Gemini family returns 400 before the provider is contacted. The SDKs raise
ValidationException; the raw response looks like:
- Video blocks are valid in user messages only, matching image input.
boto3 / AWS SDK path. The Bedrock-compatible
endpoint does not accept
video content blocks — it returns a
ValidationException listing its supported block types. Use one of the
AI Reserve SDKs or the raw OpenAI-protocol wire format above for video.