A paper boat released into a clear forest stream drifts downstream toward the lip of a small mossy waterfall, the camera following at water level past smooth stones and ferns. Natural sound: babbling water growing louder near the falls, birdsong, a distant woodpecker. Realistic motion, no text, no logos.
Veo 3.1 Fast Official Image-to-Video API
google/veo3.1-fast/image-to-videoVeo 3.1 Fast Official brings still imagery to life with high-fidelity motion. Featuring start-frame animation and smooth first-to-last frame interpolation, it balances rapid turnaround with material and lighting consistency, synchronized native audio, and up to 4K output—the workhorse for e-commerce demos and brand visual volume.
Drag and drop files, paste from clipboard, or provide a URL.
1/1 files added
Drag and drop files, paste from clipboard, or provide a URL.
1/1 files added
Examples
REST API
Quick Start
Authenticate with the API, submit the inputs and instructions, then retrieve the video using the task ID.
Connect to the Vidgo API
Create an API key, keep it only on your server, and send Authorization: Bearer VIDGO_API_KEY.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Submit one generation task
Fill in the inputs and settings for this endpoint using the request example, then save the returned task_id to query generation progress and results.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "google/veo3.1-fast/image-to-video",
"input": {
"prompt": "A paper boat released into a clear forest stream drifts downstream toward the lip of a small mossy waterfall, the camera following at water level past smooth stones and ferns. Natural sound: babbling water growing louder near the falls, birdsong, a distant woodpecker. Realistic motion, no text, no logos.",
"duration": 8,
"aspect_ratio": "16:9",
"sound": true,
"resolution": "720p",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/google/veo-3.1-fast-official/image-to-video/v1/01/input-start-frame.png",
"https://cdn.vidgo.ai/apis/models/google/veo-3.1-fast-official/image-to-video/v1/01/input-end-frame.png"
],
"generation_type": "frame"
}
}
JSON
)
RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
CODE=$(printf '%s' "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ] && [ "$CODE" != "200" ]; then
printf 'API error: %s
' "$RESPONSE" >&2
exit 1
fi
printf '%s
' "$RESPONSE"Wait for the result
Query with task_id, continue for not_started/running, and stop for finished/failed. On success, read data.files[].file_url.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll status with a 2-second base interval, and increase the interval for longer tasks. Continue only while status is not_started or running, and stop once finished or failed. You can also specify callback_url in the request payload to receive webhook notifications.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "running",
"created_time": "2026-09-17T10:00:00Z"
}
}{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "finished",
"files": [
{
"file_url": "https://storage.vidgo.ai/generated/video.mp4",
"file_type": "video"
}
],
"created_time": "2026-08-22T10:00:00Z",
"progress": 100,
"error_message": null
}
}Complete runnable example
Expand for a complete script with HTTP and business-code checks, task_id validation, polling, terminal-state handling, and a timeout boundary.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "google/veo3.1-fast/image-to-video",
"input": {
"prompt": "A paper boat released into a clear forest stream drifts downstream toward the lip of a small mossy waterfall, the camera following at water level past smooth stones and ferns. Natural sound: babbling water growing louder near the falls, birdsong, a distant woodpecker. Realistic motion, no text, no logos.",
"duration": 8,
"aspect_ratio": "16:9",
"sound": true,
"resolution": "720p",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/google/veo-3.1-fast-official/image-to-video/v1/01/input-start-frame.png",
"https://cdn.vidgo.ai/apis/models/google/veo-3.1-fast-official/image-to-video/v1/01/input-end-frame.png"
],
"generation_type": "frame"
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
BUSINESS_CODE=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Submit failed:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
START_TIME=$(date +%s)
POLL_DELAY=2
while true; do
if [ $(( $(date +%s) - START_TIME )) -ge 600 ]; then
printf 'Timed out after 600 seconds
' >&2
exit 1
fi
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
BUSINESS_CODE=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Status request failed:
%s
' "$STATUS_RESPONSE" >&2
exit 1
fi
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep "$POLL_DELAY"
if [ "$POLL_DELAY" -lt 10 ]; then POLL_DELAY=$((POLL_DELAY + 1)); fi
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneInput parameters
The table lists available input parameters, types, and defaults. Request examples also include the required top-level model field. Prepare the inputs for this task and configure the output.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| prompt | string | Yes | — | 1–1,000 characters after trimming. |
| image_urls | array | Yes | — | 1 or 2 public image URLs. Two images also send generation_type as frame. |
| generation_type | string | No | frame with two images | Optional. Omitted with one image; defaults to frame with two images. Explicit frame requires exactly two images. |
| duration | integer | No | 8 | 4, 6, or 8, in seconds. |
| aspect_ratio | string | No | 16:9 | auto, 16:9, or 9:16. |
| resolution | string | No | 720p | 720p / 1080p / 4k. |
| sound | boolean | No | true | true generates native audio; false returns a silent clip. |
Response Fields
A successful submission returns a task ID. Status queries provide progress, output files, and error details when a task fails.
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code; successful responses use 0 or 200. |
| message | string | Human-readable message or error detail when present. |
| data.task_id | string | Task ID used in the status endpoint path. |
| data.status | string | not_started, running, finished, or failed. |
| data.created_time | string | Task creation time in date-time format. |
| data.progress | integer | Task progress from 0 to 100, when included in the response. |
| data.files[] | array | All output files from a successful task, in response order. |
| data.files[].file_url | string | Public URL for a generated video. |
| data.files[].file_type | string | File type, such as video. |
| data.error_message | string | null | Failure detail when status is failed. |
Task Lifecycle
Continue querying while the status is not_started or running. End polling at finished or failed, then process the output files or error details respectively.
not_startedThe task was accepted and is waiting to begin.
runningGeneration is in progress. Continue polling the same task_id.
finishedGeneration succeeded. Read every video URL from data.files[].file_url.
failedGeneration stopped with an error. Read data.error_message and stop polling.
Polling and Errors
- AuthenticationFor a 401 response, check the Bearer API key in Authorization, update the credentials, and retry.
- ValidationFor a 400 response, use the response details to check required inputs, parameter values, and available credits, then make the indicated adjustments before submitting again.
- Network and timeoutIf a status query encounters a network error or timeout, retain the original task_id and retry the query, then handle the result according to the returned task status.
- Polling intervalPoll status with a 2-second base interval, and gradually increase the interval for longer tasks.
- Terminal statesContinue only for not_started or running. Stop immediately on finished or failed.
- Callback optionProvide callback_url at the request top level to receive the final flat task object; polling remains available if delivery fails.
Endpoint limits
| Specification | Value | Details |
|---|---|---|
| Input mode | Image plus text | A start image is required. An optional end image uses first/last-frame control. |
| Output | Video with optional native audio | The endpoint returns an asynchronous task ID; finished tasks include a video file. |
| Resolution | 720p / 1080p / 4k | Default is 720p. |
| Duration | 4 / 6 / 8 seconds | Default is 8 seconds. |
| Aspect ratio | auto / 16:9 / 9:16 | Default is 16:9. |
| Billing basis | Per second | 720p silent 10 credits/s; audio 15 credits/s. 1080p silent 10 credits/s; audio 15 credits/s. 4k silent 30 credits/s; audio 35 credits/s. |
Related Models
Veo 3.1 Fast Official Image-to-Video API frequently asked questions
What is the Veo 3.1 Fast Official Image-to-Video API?
Veo 3.1 Fast Official Image-to-Video is the balanced image-driven tier of Google's Veo 3.1 family for high-frequency production. Animate a single still from frame one or interpolate between two images with precise first/last-frame control, featuring synchronized native audio and resolutions up to 4K—ideal for e-commerce demos and brand visual volume via Vidgo API or the playground.
What model ID should I use in API requests?
Set the model field to google/veo3.1-fast/image-to-video. For Quality or Lite, use google/veo3.1/image-to-video and google/veo3.1-lite/image-to-video respectively. Do not submit URLs containing -official.
How many images can I submit and what are the modes?
You can submit 1 or 2 images. Supplying 1 image activates start-frame animation where the clip initiates from the image. Supplying 2 images activates first/last-frame mode (automatically submitting generation_type: "frame"), guiding the model to generate a seamless transition between the two states.
Does Fast image-to-video support synchronized native audio?
Yes. By setting sound: true and adding sound notes in your prompt, the generated MP4 includes action-aligned Foley, mechanical sounds, and atmospheric audio—especially valuable for shortening post work in batch pipelines.
What are the advantages of using 'auto' aspect ratio?
Choosing 'auto' preserves your source image's native aspect ratio, preventing unwanted cropping, pillarboxing, or distortion. You can also explicitly specify 16:9 or 9:16 for targeted distribution.
When should I choose Lite, Fast, or Quality?
Use Lite for rapid, cost-effective ideation and keyframe testing; choose Fast for high-throughput production requiring a balance of speed, fidelity, and 4K support; choose Quality for flagship visual fidelity and commercial-grade finals.
How does per-second pricing support batch production?
Cost is duration (4s, 6s, or 8s) multiplied by the per-second rate of your resolution and audio setting. Preview with audio off at 720p to control spend, then enable audio and elevate to 1080p/4K once motion is locked.
What image specifications are supported?
The endpoint accepts JPEG, PNG, and WebP files up to 10 MB each. High-resolution source images with clear lighting and well-defined subjects yield optimal depth extraction and motion stability.















