Video Generation API
The Video Generation API generates videos from a text prompt or an existing
image and saves the result to the asset library. Because video files are large
(typically 10–100 MB+), the API stores the hosted video URL with
isRemoteUrl: true rather than downloading the file.
- Text-to-video and image-to-video generation.
- Aspect ratios: portrait (
9:16) and landscape (16:9); image-to-video also supportsauto. - Resolutions:
720por1080p. - Durations: 4, 8, or 12 seconds. The default model caps clips at 10
seconds, so a
12request is delivered as a 10 second clip.
The models used for each capability are set by organisation administrators on the AI Usage page under Model Configuration. Both video capabilities default to Gemini Omni Flash; Sora 2 models remain available as alternatives.
Authentication
Section titled “Authentication”Every request must include:
organizationId: the tenant consuming video credits.organizationApiKey: the signed key bundled with your agent payload.
Send them in the JSON body (recommended) or as headers:
X-Organization-Id: <your-organization-id>X-Organization-Api-Key: <your-agent-api-key>Requests missing either value are rejected with 401 or 403.
Generate a video from text
Section titled “Generate a video from text”POST /api/videos/generateGenerates the video and saves the hosted video URL to the asset library with
isRemoteUrl: true.
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
organizationId | string | Yes | Organisation making the request. |
organizationApiKey | string | Yes | Signed API key from the agent payload. |
prompt | string | Yes | Detailed description of the video to generate. |
fileName | string | Yes | Name for the saved file; should end with .mp4. |
jobId | string | One of jobId/requestId | Associates the asset with a job. |
requestId | string | One of jobId/requestId | Alternative association identifier. |
description | string | No | Description stored on the asset. |
model | string | No | Omit to use the configured default (google/gemini-omni-flash). Unknown values fall back to the default. |
resolution | string | No | 720p or 1080p. Defaults to 720p. Ignored by the default model, which outputs 720p only. |
aspectRatio | string | No | 9:16 or 16:9. Defaults to 16:9. |
duration | string | No | 4, 8, or 12 seconds. Defaults to 4. The default model delivers a 12 request as 10 seconds. |
metadata | object | No | Additional metadata stored on the asset. |
createdByAgentType | string | No | Agent type for tracking. Defaults to ai-agent. |
Example request
Section titled “Example request”curl -X POST https://api.runnit.io/api/videos/generate \ -H "Content-Type: application/json" \ -d '{ "organizationId": "<your-organization-id>", "organizationApiKey": "<your-agent-api-key>", "jobId": "your-job-id", "prompt": "A sleek product reveal: a modern smartphone slowly rotating on a minimalist white surface, dramatic side lighting, camera slowly dolly in, premium feel", "fileName": "product_reveal.mp4", "description": "Product reveal video for smartphone launch", "aspectRatio": "9:16", "resolution": "720p", "duration": "4", "createdByAgentType": "copywriter" }'Response
Section titled “Response”{ "success": true, "message": "Video generated and URL saved successfully", "asset": { "id": "asset-uuid", "fileName": "product_reveal.mp4", "fileType": "video", "mimeType": "video/mp4", "videoUrl": "https://.../output.mp4", "description": "AI-generated video: ...", "createdAt": "2025-10-14T12:00:00Z" }, "generationInfo": { "model": "google/gemini-omni-flash", "prompt": "A sleek product reveal...", "resolution": "720p", "aspectRatio": "16:9", "duration": "4 seconds", "videoId": "video_123", "width": 1280, "height": 720, "fps": 30 }}Generate a video from an image
Section titled “Generate a video from an image”POST /api/videos/generate-from-imageTakes a single source image URL, generates motion, and saves the resulting
hosted video URL to the asset library with isRemoteUrl: true.
Request body
Section titled “Request body”In addition to the shared fields above:
| Field | Type | Required | Description |
|---|---|---|---|
imageUrl | string | Yes | Publicly accessible URL of the source image. |
aspectRatio | string | No | 9:16, 16:9, or auto. Defaults to auto. On the default model, auto uses the model’s own framing. |
duration | string | No | 4, 8, or 12 seconds. Defaults to 4. The default model delivers a 12 request as 10 seconds. |
model | string | No | Omit to use the configured default (google/gemini-omni-flash/image-to-video). Unknown values fall back to the default. |
The source image must be reachable without authentication. The resulting video is 720p by default.
Example request
Section titled “Example request”curl -X POST https://api.runnit.io/api/videos/generate-from-image \ -H "Content-Type: application/json" \ -d '{ "organizationId": "<your-organization-id>", "organizationApiKey": "<your-agent-api-key>", "jobId": "your-job-id", "prompt": "Slow tracking shot of the car driving along the coastline at golden hour, wind in the palm trees, cinematic lighting", "imageUrl": "https://example.com/still_beach_car.jpg", "fileName": "beach_drive.mp4", "description": "Animated hero visual for paid social", "aspectRatio": "auto", "duration": "8", "createdByAgentType": "copywriter" }'Response
Section titled “Response”{ "success": true, "message": "Video generated from image and URL saved successfully", "asset": { "id": "asset-uuid", "fileName": "beach_drive.mp4", "fileType": "video", "mimeType": "video/mp4", "videoUrl": "https://.../output.mp4", "description": "Animated hero visual for paid social", "createdAt": "2025-11-04T12:00:00Z" }, "generationInfo": { "model": "google/gemini-omni-flash/image-to-video", "prompt": "Slow tracking shot of the car...", "aspectRatio": "auto", "duration": "4", "videoId": "request-or-video-id", "sourceImageUrl": "https://example.com/still_beach_car.jpg" }}Capability and status endpoints
Section titled “Capability and status endpoints”These endpoints report the supported options and service availability. All require organisation credentials.
GET /api/videos/modelsGET /api/videos/resolutionsGET /api/videos/aspect-ratiosGET /api/videos/image-to-video/aspect-ratiosGET /api/videos/durationsGET /api/videos/image-to-video/durationsGET /api/videos/statusFor example, GET /api/videos/models:
{ "success": true, "models": [ "google/gemini-omni-flash", "google/gemini-omni-flash/image-to-video", "fal-ai/sora-2/text-to-video/pro", "fal-ai/sora-2/image-to-video/pro", "fal-ai/sora-2/image-to-video" ], "default": "google/gemini-omni-flash", "imageToVideoDefault": "google/gemini-omni-flash/image-to-video"}The default and imageToVideoDefault values reflect the models configured on
the AI Usage page.
And GET /api/videos/status:
{ "success": true, "available": true, "message": "Video generation service is available"}Error responses
Section titled “Error responses”| Status | Meaning |
|---|---|
400 Bad Request | Invalid parameters, validation failed, or missing jobId/requestId. |
403 Forbidden | Organisation doesn’t have permission to generate videos. |
404 Not Found | Organisation or job not found. |
500 Internal Server Error | Video generation failed. |
503 Service Unavailable | Video generation service is not configured. |
Storage behaviour
Section titled “Storage behaviour”Videos are not downloaded to Runnit. Only the hosted video URL is stored, with
isRemoteUrl: true, and the video can be streamed or embedded directly from
that URL. When accessing video assets through the File API or
the asset browser, the content field contains the remote video URL.
Writing effective prompts
Section titled “Writing effective prompts”- Be specific about subject, setting, lighting, and mood.
- Include camera movement (e.g. “camera slowly dolly in”, “tracking shot”).
- Define composition and style (e.g. “rule of thirds”, “cinematic”).
- Avoid readable text and specific real people: keep human elements general.
Platform recommendations
Section titled “Platform recommendations”| Platform | Aspect ratio | Resolution | Duration |
|---|---|---|---|
| Instagram Stories / Reels | 9:16 | 720p | 4–8s |
| TikTok | 9:16 | 720p | 4–12s |
| YouTube | 16:9 | 1080p | 8–12s |
16:9 | 1080p | 4–8s | |
| Twitter/X | 16:9 | 720p | 4–8s |
16:9 | 720p | 4–8s |
Generation requests are synchronous: the response returns once the clip has been generated and the asset saved, so allow a generous request timeout.