Skip to main content
POST
Creates a new land transformation video from a single photo of an empty plot. The system progressively builds the land through chained transitions: raw terrain → marked buildable area → proposed constructions. Each transition is rendered as a cinematic morph, resulting in a fluid visualization of what the land could become. This endpoint is progressive — only source_image_url and format are required. Everything else is optional and resolved server-side if omitted:
  • No mask? The server auto-detects the buildable area via Gemini.
  • No scenes? The server generates construction proposals based on terrain analysis.
  • No script? The server auto-generates a narration script.
When you provide pre-generated assets (scenes[], script, mask_image_url), the server skips the corresponding generation steps. This avoids double-charging for assets you already created.

Request Body

string
required
Publicly accessible URL of a single photo of an empty plot of land.
  • Must be a valid HTTP(S) URL
  • Must be an image file (JPEG, PNG, or WebP)
  • Only one image is accepted
Every image URL in the request is fetched and validated before the task is created. Unreachable images fail with 400 INVALID_IMAGE_URL, and images below the minimum resolution fail with 400 IMAGE_RESOLUTION_TOO_LOW. VibePeak-hosted assets belonging to another account are rejected with 403 ASSET_ACCESS_DENIED.
string
required
Target video format / aspect ratio.

Mask & Area Overrides

string
Optional binary mask image (PNG) marking the buildable area with a neon outline and semi-transparent fill.When provided, the server uses this mask directly and skips auto-detection. Takes precedence over area_polygon.Alias: mask_url is accepted and normalized to mask_image_url. If both are sent, mask_image_url wins.
string
Optional pre-rendered marked terrain image (the img1 frame — the source photo with the buildable area already highlighted).When provided, the server skips the marking render entirely and uses this frame directly. Like mask_image_url and area_polygon, supplying it waives the 5-credit mask charge, and the task reports marking: "mask".It takes precedence over both mask_image_url and area_polygon.
marked_image_url also changes how the frame count is calculated when you supply scenes[] — see Frame Limits.
object[]
Optional polygon coordinates marking the buildable area. Minimum 3 points required.Each point is an object with normalized coordinates:Alias: polygon is accepted and normalized to area_polygon.If none of mask_image_url, area_polygon or marked_image_url is provided, the server auto-detects the buildable area using Gemini vision analysis.

Terrain & Construction Overrides

string
Optional terrain type hint, e.g. "urban", "rural" or "industrial".Any non-empty string is accepted — the value is a free-form hint passed to the proposal generator, not a closed enum. If omitted, the server analyzes the image and auto-detects the terrain type.
string[]
Optional array of construction prompts (1-8). One image is generated per prompt in the order provided.When provided, the server skips proposal auto-generation and renders exactly these constructions. Each prompt is still billed as a generated scene.Alias: prompts is accepted and normalized to construction_prompts.
integer
default:"3"
Optional number of constructions to auto-generate (2-8). Default is 3.Ignored if scenes or construction_prompts are provided.
string
Optional style hint that biases auto-generated proposals (e.g., "modern", "rustic", "minimalist").
string
Optional exclusion hint for auto-generated proposals (e.g., "no swimming pools", "no glass facades").

Scene Chain (Fully Resolved)

object[]
Optional fully-resolved scene chain (1-8 items). When provided, the server skips scene generation and renders these frames directly.Each scene is an object with:
Providing scenes[] is the recommended path for first-party callers (like the VibePeak web app) that have already generated images interactively. This ensures you are only charged the base render cost (15 credits) and avoids double-charging for generated assets.

Script, Voice & Music Overrides

string
Optional narration script for text-to-speech. Any non-empty string is accepted.
Unlike the narrated slideshow and real-estate endpoints, /v1/land does not enforce a character-count range or reject digits and symbols. For natural pacing aim for roughly 65-85 characters per scene, but this is guidance, not validation.
string
Language code for the auto-generated script and TTS pronunciation (e.g., en, es, de, fr, pt). Minimum 2 characters.
string
Voice ID for narration. You can find available voices using the List Voices endpoint.Defaults to a platform voice if omitted.
boolean
Set to false to render the video without narration. When false, the server skips text-to-speech entirely and script / voice_id may be omitted.Omitting this field leaves narration on.
boolean
Set to true to add a background music bed. Omitting this field, or sending false, renders the video without music.
string
Optional Music Library track to pin, as a UUID. Without it, a background_music: true job uses a randomly selected bed.
music_id and music_kind must be sent together — sending one without the other fails with 400 VALIDATION_ERROR (music_id and music_kind must be provided together). A non-UUID value fails with music_id must be a valid UUID.Both fields are only honored when background_music is true; with music off the video stays silent regardless.
string
Which catalogue music_id refers to: stock (Music Library track) or ai (AI-generated track). Required whenever music_id is present.

Subtitle & Elements Configuration

object
Subtitle configuration for word-level animated overlays. Same structure as other video endpoints — see Create Narrated Slideshow for the full field list.On this endpoint the object is passed through to the renderer without field-level validation, so a malformed key is accepted at request time and simply ignored downstream.
object
Configuration for visual elements and branding overlays (watermark, text, intro/outro). Same structure as other video endpoints — see Create Narrated Slideshow.The intro_outro block is fully validated; the rest is passed through to the renderer. Browse the designs in the template gallery, or read the catalogue from GET /v1/intro-outro/templates.As on Create Narrated Slideshow, the overlays are applied after the video renders. The task passes through the transitional intro_outro status while that runs, and if the overlays cannot be applied the task still completes: the video is delivered without them and the result carries an intro_outro_warning.
Unlike the real-estate and narrated-slideshow endpoints, /v1/land does not pre-validate the watermark URL at request time, so it never returns INVALID_WATERMARK_URL. An unreachable watermark surfaces later as a render failure. Verify the URL before submitting.

Webhook

string
HTTPS URL to receive a webhook notification when the task completes or fails.See Webhooks for payload format and verification details.
Webhook URLs must use HTTPS and cannot point to private/internal networks (SSRF protection). A rejected URL fails with 400 INVALID_WEBHOOK_URL.

Response

Returns a 202 Accepted response. Unlike other video endpoints, land tasks start in the preparing state while the server resolves inputs (auto-detecting the mask, generating scenes, creating the script), and they report credits under charged_credits with a resolution object.
Land responses are deliberately shaped differently from other video endpoints. Land tasks use charged_credits and a resolution object; every other task type uses credits_charged and has no resolution. If you share response-parsing code across endpoints, handle both key names.
string
required
Unique identifier for the task, in the form task_<id>. Use this to poll for status via Get Task.
The task_id sent in the webhook payload is a different identifier (vp_land_<id>, the task’s external id). Correlate webhooks by storing both, or by matching on your own reference — do not assume the webhook task_id can be passed to GET /v1/tasks/{id}.
string
required
Initial task status. Always preparing for land tasks.
string
required
Human-readable acknowledgement — "Land transformation request accepted".
string
required
ISO 8601 timestamp of task creation.
boolean
required
true for live keys. Requests made with a vpk_test_ key return false and are not charged — see Test Mode.
string
required
Request identifier, useful when contacting support.
integer
required
Credits actually deducted for this request. See Credit Model for the breakdown.
object
Preparation metadata describing what the server will compute.
Convenience links: self (the poll URL) and poll_interval_seconds.

Response Headers

Credit Model

Land transformation videos use a differentiated credit model based on the work the server performs: When scenes[] is absent, the number of generated scenes is construction_prompts.length, else num_constructions, else 3. Example costs:
Assets you pre-provide (scenes[], script, mask_image_url, marked_image_url) are never regenerated and never re-charged. This prevents double-charging for first-party callers that already generated images interactively.
Credits are deducted at creation time. If the job later fails, the credits are refunded automatically — the webhook’s charged_credits reflects the post-refund amount (typically 0).

Plan Access

Frame Limits

The video chain must contain 3 to 10 total frames. How the count is derived depends on whether you supply scenes[]:
  • Without scenes[] — the count is 2 + n, where n is construction_prompts.length, else num_constructions, else 3. The two implied frames are img0 (original terrain) and img1 (marked terrain).
  • With scenes[] — the count is 1 + (marked_image_url ? 1 : 0) + scenes.length. img1 is only counted when you actually supply marked_image_url.
A resolved chain of 3 scenes with no marked_image_url counts as 4 frames, not 5. If you are supplying a chain that already includes the marked frame as its first scene, do not also send marked_image_url — you would count it twice.
Requests outside the 3-10 range fail with 400 VALIDATION_ERROR on the scenes field.

Polling

Land tasks flow through preparingqueuedprocessingcompleted or failed. If the request asked for post-processing, the task also reports a transitional status between processing and its final state, in this order: watermarking, intro_outro, subtitling. Each appears only when the corresponding feature was requested. Treat all three like processing and keep polling — the task always ends in completed or failed. A step that cannot finish does not fail the task: the video is delivered without that refinement and result carries a matching watermark_warning, intro_outro_warning or subtitle_warning. See Asynchronous Processing. While in preparing, GET /v1/tasks/{task_id} returns a resolution object that advances through these stages: Not every task passes through every stage. Supplying marked_image_url or mask_image_url resolves marking synchronously, so a fully-resolved request skips the intermediate stages and reports resolved / 100 on the first poll. Treat the ladder as monotonic but sparse — do not wait for a specific stage to appear. Once marking is decided, the resolution object also carries marking, generated_image_count and used_overrides. It also carries resolved_inputs — a whitelisted view of what the server actually resolved (source_image_url, format, mask_image_url, area_polygon, terrain_type, scenes, construction_prompts, script), which is how you retrieve the generated scene image URLs and the auto-written script. Your webhook_url and other request fields are deliberately not echoed back. generated_image_count counts server-generated scene images plus one for an auto-generated mask, and stays 0 for a fully-resolved request. On land tasks the GET response uses charged_credits; other task types use credits_charged.
Tasks expire 24 hours after creation. After that, GET /v1/tasks/{task_id} returns 404 TASK_EXPIRED and the video URL is no longer retrievable — download the result before then.

Webhook Payload

When the task completes or fails, a POST request is sent to your webhook_url. See Webhooks for verification.

Webhook Headers

The signed message is {timestamp}.{raw body}, not the body alone. Concatenate the X-VibePeak-Timestamp value, a literal ., and the exact raw request body before computing the HMAC, or verification will fail.
The event name lives in the X-VibePeak-Event header, not in the body. There is no event field inside the JSON.

Payload

For failed tasks:
The webhook task_id is the task’s external id (vp_land_<id>), which is not the task_id returned by POST /v1/land (task_<id>) and cannot be passed to GET /v1/tasks/{id}. Store the value returned at creation and correlate on your side.
Notes on the payload:
  • resolution is the typed shape only — marking, generated_image_count, used_overrides. It does not include stage, progress or credits_breakdown; those appear only on the polling response.
  • resolution is omitted entirely if marking was never resolved (for example, a failure during preparation).
  • result carries only video_url and cover_image_url. There is no duration_seconds, resolution or expires_at inside result.
  • cover_image_url is present only if cover generation succeeded. Note that it is keyed by the internal task_<id>, while the payload’s task_id is the vp_land_<id> external id.
  • There is no event, type or timestamp field in the body. Distinguish outcomes with status, or read the X-VibePeak-Event header.
The marking field indicates which method was used to identify the buildable area:

Error Codes

Asynchronous failures are reported through the task’s error object and the failure webhook: See Error Handling for more details.

Next Steps

After creating a task:
  1. Poll for status: Use Get Task with the task_id from the 202 response, every 30 seconds.
  2. Wait for webhook: If configured, receive notification when complete — remembering the id difference noted above.
  3. Download video: Access result.video_url within 24 hours of creation.