One endpoint turns a list of photo URLs into a presentation video. Get your API key from the dashboard, then follow the quickstart below.
The endpoint also publishes live, auto-generated interactive documentation. It follows the same
request/response schema described below, but with a "Try it out" button that lets you
send a real request straight from your browser (use test_mode: "TRUE" to
test for free).
images array counts as one photo.test_mode: "TRUE" generations are free (lower-quality preview).1. Start a generation. While integrating, keep test_mode: "TRUE". It costs
no credits and returns a quick placeholder video so you can validate your integration end
to end. Once everything is wired up, switch it to "FALSE" to see a real
result (real generations take 4–5 minutes; test-mode ones finish in under a minute).
curl -X POST https://immo-512624703714.europe-west1.run.app/ \
-H "Content-Type: application/json" \
-d '{
"name": "123-rue-exemple",
"vikit_api_key": "YOUR_API_KEY",
"images": [
"https://example.com/photo1.jpg",
"https://example.com/photo2.jpg"
],
"music_url": "https://storage.googleapis.com/real-estate-musics/aube_doree.mp3",
"target_ratio": "16:9",
"test_mode": "TRUE"
}'
Response:
{
"Generation_id": "v-1234...",
"Result_url": "https://immo-512624703714.europe-west1.run.app/get/v-1234..."
}
2. Poll Result_url until state is "Completed"
(or "Error"). A common integration pattern: trigger the generation from your
backend, then poll Result_url from a small script in your frontend so the
user sees live progress without you needing a webhook.
curl https://immo-512624703714.europe-west1.run.app/get/v-1234...
Example completed response:
{
"state": "Completed",
"progress": 100,
"name": "123-rue-exemple",
"arrayOfImages": ["https://example.com/photo1.jpg", "https://example.com/photo2.jpg"],
"timestamp": 1783150376.29,
"quality_tier": 1,
"videos": [
"https://storage.googleapis.com/.../123-rue-exemple_....mp4",
"https://storage.googleapis.com/.../123-rue-exemple_1_....mp4",
"https://storage.googleapis.com/.../123-rue-exemple_2_....mp4",
"https://storage.googleapis.com/.../123-rue-exemple_..._vertical.mp4"
]
}
The videos array order is fixed:
images (handy if you want to offer clients both the full video and the
per-photo clips)._vertical): the final video again,
cropped to vertical (9:16). The standard front-end pattern is to offer this one plus the
first (horizontal) entry.| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Label for this generation (used in filenames/logs). |
vikit_api_key | string | yes | Your API key from the dashboard. |
images | string[] | yes | Ordered list of photo URLs. One photo = one credit (0.50 €). |
music_url | string | no | Background music URL. Any hosted audio file, not just the tracks below. Default: none. See Background music. |
ending_media_url | string | no | Image/video appended at the end (e.g. an agency outro). |
logo_url | string | no | Logo overlay on the video. |
target_ratio | string | no | "16:9" (default) or "9:16". The API does not crop your photos to match. Send photos already close to this ratio for the best result. (The web dashboard crops photos for you automatically.) |
test_mode | string | no | "TRUE" for a free, lower-quality preview. Default: "FALSE". |
notify_email | string | no | If set, an email is sent to this address when the video is ready (or if generation fails, along with a note that credits were refunded). Default: none. |
GET /get/{generation_id})| Field | Description |
|---|---|
state | One of "Starting job", "Processing_video", "Completed", "Error". Poll until "Completed" or "Error". |
progress | 0–100. Reaches 100 only once state is "Completed". |
videos | Only present once state is "Completed". See the ordering explained above. |
error | Only present when state is "Error". Human-readable failure reason; any debited credits are already refunded by the time this appears. |
name, arrayOfImages, timestamp | Echoed back from your request, plus the server timestamp of the last update. Responses may contain additional internal fields (e.g. quality_tier). Safe to ignore. |
music_url accepts any publicly reachable audio file URL. Host your
own track wherever you like. If you don't have one ready, these royalty-free ambient
tracks are available for you to use directly:
| Track | URL |
|---|---|
| Aube dorée (default for web-portal videos) | https://storage.googleapis.com/real-estate-musics/aube_doree.mp3 |
| Brise de cristal | https://storage.googleapis.com/real-estate-musics/brise_de_cristal.mp3 |
| Brume enchantée | https://storage.googleapis.com/real-estate-musics/brume_enchantee.mp3 |
| Bulle de rêve | https://storage.googleapis.com/real-estate-musics/bulle_de_reve.mp3 |
| Cascade céleste | https://storage.googleapis.com/real-estate-musics/cascade_celeste.mp3 |
| Danse du crépuscule | https://storage.googleapis.com/real-estate-musics/danse_du_crepuscule.mp3 |
The web dashboard lets you pick any of the tracks above, a
custom URL, or no music, right in the generation form (defaults to "Aube dorée"). Direct
API calls have no music unless you set music_url yourself. Set it to one of
the URLs above, or to your own hosted audio file.
All errors are returned as HTTP 200 with an Error field (no exceptions thrown on the wire):
| Response | Meaning |
|---|---|
{"Error": "There is not such Vikit API Key registered..."} |
The vikit_api_key doesn't match any account. |
{"Error": "Insufficient credits", "credits_remaining": 0, "top_up_url": "..."} |
Not enough credits for the number of photos in this request. No job was started, no charge made. Follow top_up_url to buy more. |
{"Error": "..."} (generation failure) |
Something failed during video generation. Any credits debited for this generation are automatically refunded. |