# Vidom API — Developer Guide (LLM-readable) > This is the complete, self-contained reference for the Vidom API: AI video and > image generation over a single HTTP API. It is written to be read in full by a > coding assistant (e.g. Claude Code). Fetch this file, then implement against it. > > Base URL: the origin you fetched this file from. The examples below use > `$VIDOM_BASE` — set it to that origin (e.g. `export VIDOM_BASE=https://vidom.ai`). > Interactive Swagger UI: `/docs` · Raw OpenAPI JSON: `/openapi.json` > > The important non-obvious rules: (1) generation is asynchronous — poll or use a > webhook, never expect a synchronous result (images can opt into `sync`); > (2) never hardcode credit prices or option sets — read them live from > `GET /v1/products`; (3) the response's `cost` field is the source of truth for > what a call charged. --- ## What's new - **Restyle** — `POST /v1/image/restyle` and `POST /v1/video/restyle` apply a preset style (browse `GET /v1/styles`). - **Uploads** — `POST /v1/uploads` gives you a direct-to-CDN URL for hosting large input files. - **Image generation** — `POST /v1/image/generate` (flat price, optional `sync`). - **Video edit / restyle** — transform a clip from a text instruction or a preset style; keeps the source audio. - **Upscale / reframe / frames / avatar / motion control / effects / extend** — see the reference below. Tiers are named `*-fast` / `*-max` (or `std` / `pro` for avatar). You never name an underlying model — pick a tier, we route it. --- ## Quickstart ### 1. Authenticate Every `/v1/*` call needs your API key in a header: ``` X-API-Key: sk_your_key_here ``` ### 2. Start a generation (returns immediately, status `pending`) ```bash curl -X POST $VIDOM_BASE/v1/video/image-to-video \ -H "X-API-Key: sk_your_key" -H "Content-Type: application/json" \ -d '{"image_url":"https://example.com/photo.jpg","provider":"vidom","model":"vidom-fast","prompt":"gentle zoom in"}' ``` Response: ```json { "id": "gen_abc123", "status": "pending", "cost": 100, "credits_charged": 100, "estimated_duration_seconds": 135 } ``` ### 3. Get the result — poll OR webhook **Poll** `GET /v1/video/:id` until `status` is `completed` or `failed`: ```bash curl $VIDOM_BASE/v1/video/gen_abc123 -H "X-API-Key: sk_your_key" ``` ```json { "id": "gen_abc123", "status": "completed", "output": { "url": "https://cdn.vidom.ai/generations/acc_1/gen_abc123/output.mp4", "type": "video/mp4", "duration_seconds": 5 } } ``` **Webhook (preferred):** pass `"webhook_url": "https://your-server/callback"` on the create call and we POST you the result on completion/failure. See *Webhooks* below. You can also do both — treat any webhook as a "go re-fetch" signal. --- ## Core concepts **Asynchronous.** Create calls return `pending`/`processing` with an `id`. The video/image is produced in the background (seconds to several minutes depending on the feature). Never block on the create response for a result. (Exception: `POST /v1/image/generate` with `sync: true`, and `POST /v1/image/restyle`, return the finished image directly.) **Credits.** Each account has a credit balance. A create call charges credits up front and returns the amount in `cost` / `credits_charged`. If you cancel, credits are **not** returned (the provider still bills the job). If a generation *fails* on our side, credits are refunded automatically. **Live pricing — never hardcode.** Prices are in credits and can change. Read them at runtime: ```bash GET /v1/products # every model with its price + capabilities GET /v1/products?feature=text-to-video # filter by feature ``` Each product's `price` is a plain credit amount in the feature's natural unit (`per: "second"` / `"5 seconds"` / `"image"`). The EXACT charge for any call is always returned as the `cost` field on the create response — trust that. **Supported options — read them, don't hardcode.** Every product on `GET /v1/products` also carries a `capabilities` block describing what that model/tier supports, so your UI can populate its toggles (model, audio, aspect ratio, duration) directly from the API. It's generated from the same source that validates requests, so it can never disagree with what the API accepts. ```json // GET /v1/products?feature=text-to-video → one entry per model: { "model": "vidom-fast", "price": { "credits": 14, "per": "second" }, "capabilities": { "audio": true, "durations": [5, 10], // when audio is off "durations_with_audio": [3,4,5,6,7,8,9,10,11,12,13,14,15], "aspect_ratios": ["16:9", "9:16", "1:1"], "resolutions": null, "frame_rates": null, "input": null } } ``` Drive your toggles from it: the duration dropdown = `audio ? durations_with_audio : durations`; show the audio toggle only when `audio` is true; populate aspect ratios / resolutions / frame rates from their arrays (a `null` field means that parameter doesn't apply to this feature). This is why `vidom-fast` without audio offers only 5 or 10 while `vidom-max` (or fast + audio) offers 3–15 — you never have to encode that rule yourself; it's in the response. **Tiers, not models.** Pick a quality tier (`vidom-fast`/`vidom-max`, `edit-fast`/`edit-max`, `frames-fast`/`frames-max`, `motion-fast`/`motion-max`, avatar `std`/`pro`). We map it to the right underlying engine and resolution. **Inputs — three ways to provide media.** Any `image_url` / `video_url` / `audio_url` / `images[]` field accepts: 1. **An `https://` URL** we can fetch (the simplest option). 2. **An inline base64 data URI** (`data:;base64,...`) for small files — capped at ~22MB so it can't blow the request limit. 3. **An uploaded file.** For large files, call `POST /v1/uploads` to get a presigned URL, `PUT` the bytes there, then pass the returned `file_url`. See the Inputs section below. We keep a durable copy of every input we accept (returned as `input_files` on the generation), so a result stays reproducible even if your original URL goes away. **Outputs — permanent CDN URLs.** `output.url` on a completed generation is a stable, cacheable URL on our CDN with **no expiry** — you can serve it directly or download it. `output.type` is the MIME type (`video/mp4`, `image/jpeg`, …). Videos also carry `output.duration_seconds`. **Adult content (`disable_safety_checker`).** On the generation endpoints that support it (vidom), default `false` = SFW only (adult content blocked). Set `true` to allow adult (18+) content. Content involving minors or otherwise illegal content is always blocked and cannot be enabled. **Durations.** `duration` is in whole seconds and its allowed set depends on the tier — you don't have to encode it, it's in each product's `capabilities` (`durations` / `durations_with_audio`). As a rule of thumb: `vidom-max`, any `audio: true` request, and `frames-max` accept **3–15s**; `vidom-fast` without audio and `frames-fast` accept **5 or 10**. Out-of-range values are rejected at request time (clean `400`, no charge). --- # Endpoints All bodies are JSON. All require the `X-API-Key` header. Every create call also accepts an optional `webhook_url`. Where a field is omitted, its default applies. ## Generate video ### POST /v1/video/text-to-video Generate a video from a text prompt. - Async: returns `status: "pending"` immediately — poll `GET /v1/video/:id` or pass a `webhook_url`. - Priced per second (see `GET /v1/products`). The exact charge is the `cost` field on the response. Full spec (interactive): /docs#/Video/post_v1_video_text-to-video | field | type | required | default | description | |---|---|---|---|---| | `prompt` | string | **yes** | — | Text prompt describing the video. Max 2500 chars. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | | `duration` | integer | no | `5` | Clip length in seconds. Allowed values depend on the model/tier and audio — see the capabilities block on GET /v1/products. | | `aspect_ratio` | "16:9" \| "9:16" \| "1:1" | no | `"16:9"` | Output aspect ratio. | | `audio` | boolean | no | `false` | Generate native audio (where the model supports it). | | `disable_safety_checker` | boolean | no | `false` | Vidom only: false (default) keeps safety on (SFW); true allows adult (18+). Minors/illegal are always blocked. | | `multi_shot` | boolean | no | `false` | Native multi-shot; requires provider=vidom and model=vidom-max. | Example request body: ```json { "prompt": "a red fox trotting through fresh snow, cinematic", "provider": "vidom", "model": "vidom-max", "duration": 8, "audio": true } ``` --- ### POST /v1/video/image-to-video Animate a still image into a video. - Async: poll `GET /v1/video/:id` or pass a `webhook_url`. - Priced per second. `image_url` may be an https URL or an inline base64 data URI (see Inputs). Full spec (interactive): /docs#/Video/post_v1_video_image-to-video | field | type | required | default | description | |---|---|---|---|---| | `image_url` | string | **yes** | — | Source image to animate: an https URL or a base64 data URI (max ~22MB). | | `prompt` | string | no | `""` | Optional text prompt guiding the motion. Max 2500 chars. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | | `duration` | integer | no | `5` | Clip length in seconds. Allowed values depend on the model/tier and audio — see the capabilities block on GET /v1/products. | | `audio` | boolean | no | `false` | Generate native audio (where the model supports it). | | `disable_safety_checker` | boolean | no | `false` | Vidom only: false (default) keeps safety on (SFW); true allows adult (18+). Minors/illegal are always blocked. | | `multi_shot` | boolean | no | `false` | Accepted for symmetry only; multi_shot is supported on text-to-video, rejected here if true. | Example request body: ```json { "image_url": "https://example.com/photo.jpg", "provider": "vidom", "model": "vidom-fast", "prompt": "gentle zoom in", "duration": 5 } ``` --- ### POST /v1/video/extend Continue an existing video with more generated footage. - The extension is a Vidom clip — pick a tier (`vidom-fast` / `vidom-max`), not an underlying model. - Source video ≤ 150MB. Priced like a Vidom clip of the same tier / duration / audio. Full spec (interactive): /docs#/Video/post_v1_video_extend | field | type | required | default | description | |---|---|---|---|---| | `video_url` | string | **yes** | — | Source video to extend (https URL or base64 data URI); the continuation starts from its last frame. | | `prompt` | string | no | `""` | Optional text prompt guiding the continuation. Max 2500 chars. | | `model` | string | no | `null` | Quality tier: vidom-fast (default) or vidom-max. | | `duration` | integer | no | `5` | Length of the added continuation in seconds. Allowed values depend on the tier and audio — see the capabilities block on GET /v1/products. | | `audio` | boolean | no | `false` | Generate native audio for the continuation. | | `disable_safety_checker` | boolean | no | `false` | Vidom only: false (default) keeps safety on (SFW); true allows adult (18+). Minors/illegal are always blocked. | Example request body: ```json { "video_url": "https://example.com/clip.mp4", "model": "vidom-fast", "duration": 5, "prompt": "the camera keeps panning right" } ``` --- ### POST /v1/video/effects Apply a named preset effect to one or more images. - Browse the ~297 effects at `GET /v1/effects` and pass the effect's `key` as `effect`. - Single-image effects use `image_url`; the two-image effects use `images: [a, b]` (see each effect's `input.count`). - Output is a fixed 5-second clip; flat price per effect. Full spec (interactive): /docs#/Video/post_v1_video_effects | field | type | required | default | description | |---|---|---|---|---| | `image_url` | string | no | `null` | Single input image (https URL or base64 data URI); provide this or `images`. | | `images` | array<string> | no | `null` | 1-10 input images for effects that take multiple; provide this or `image_url`. | | `effect` | string | **yes** | — | Effect key to apply; see GET /v1/effects for the catalog. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | Example request body: ```json { "image_url": "https://example.com/photo.jpg", "effect": "puff_cheeks" } ``` ## Generate image ### POST /v1/image/generate Generate an image from a text prompt. - Flat price per image. Prompt may be in any language (auto-translated). - Set `sync: true` to hold the connection and get the finished image in the response (`status: "completed"` + `output.url`) — no polling. Falls back to async if it runs long. Full spec (interactive): /docs#/Image/post_v1_image_generate | field | type | required | default | description | |---|---|---|---|---| | `prompt` | string | **yes** | — | Text prompt describing the image. Max 2500 chars. | | `aspect_ratio` | "1:1" \| "16:9" \| "9:16" \| "4:3" \| "3:4" \| "3:2" \| "2:3" | no | `"1:1"` | Output aspect ratio; supported values are advertised on GET /v1/products. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | | `disable_safety_checker` | boolean | no | `false` | Vidom only: false (default) keeps safety on (SFW); true allows adult (18+). Minors/illegal are always blocked. | | `sync` | boolean | no | `false` | When true, hold the connection and return status=completed with output.url (falls back to async if it runs long). | Example request body: ```json { "prompt": "a watercolor koi pond at dawn", "aspect_ratio": "16:9", "sync": true } ``` --- ### POST /v1/image/restyle Apply a preset style to an existing image. - Browse styles at `GET /v1/styles` and pass the style's `key` as `style`. - Synchronous — the response already carries `status: "completed"` + `output.url`. Omit `aspect_ratio` to keep the input's shape. Full spec (interactive): /docs#/Image/post_v1_image_restyle | field | type | required | default | description | |---|---|---|---|---| | `image_url` | string | **yes** | — | Source image to restyle (https URL or base64 data URI); runs synchronously. | | `style` | string | **yes** | — | Preset style key; see GET /v1/styles for the catalog. | | `aspect_ratio` | "1:1" \| "16:9" \| "9:16" \| "4:3" \| "3:4" \| "3:2" \| "2:3" | no | optional | Omit to preserve the input's shape; set to force an output aspect ratio. | Example request body: ```json { "image_url": "https://example.com/photo.jpg", "style": "watercolor" } ``` ## Transform video ### POST /v1/video/edit Transform a video from a text instruction (change weather, objects, style). - Keeps the source audio and length. Input 3–15.5s, ≤ 200MB. Priced per second of the source. - Input is validated before charge — bad input returns `400` and charges nothing. - Source width and height must both be 700–4553px. Smaller videos are upscaled automatically so the call still succeeds, but upscaling cannot add detail — send the highest resolution you have. Phone and social exports are often well below this floor. Full spec (interactive): /docs#/Video/post_v1_video_edit | field | type | required | default | description | |---|---|---|---|---| | `video_url` | string | **yes** | — | Source video to edit (https URL or base64 data URI); 3-15.5s, max 200MB. Its own audio is preserved. | | `prompt` | string | **yes** | — | Text instruction describing the edit. Max 2500 chars. | | `model` | string | no | `null` | Quality tier: edit-fast (720p) or edit-max (1080p); null = default. | Example request body: ```json { "video_url": "https://example.com/clip.mp4", "prompt": "make it snow over the beach", "model": "edit-fast" } ``` --- ### POST /v1/video/restyle Apply a preset style to a video. - Browse styles at `GET /v1/styles`. Runs on the Omni edit tiers — `fast` (720p) / `max` (1080p). - Input 3–15.5s, ≤ 200MB. Priced per second of the source; keeps the source audio. Full spec (interactive): /docs#/Video/post_v1_video_restyle | field | type | required | default | description | |---|---|---|---|---| | `video_url` | string | **yes** | — | Source video to restyle (https URL or base64 data URI); priced per second of the source. | | `style` | string | **yes** | — | Preset style key; see GET /v1/styles for the catalog. | | `model` | "fast" \| "max" | no | `"fast"` | Quality tier: fast (720p) or max (1080p). | Example request body: ```json { "video_url": "https://example.com/clip.mp4", "style": "claymation", "model": "fast" } ``` --- ### POST /v1/video/reframe Change a video's aspect ratio. - Output is always 720p. Input ≤ 30s, ≤ 100MB. Priced per second of the source. Full spec (interactive): /docs#/Video/post_v1_video_reframe | field | type | required | default | description | |---|---|---|---|---| | `video_url` | string | **yes** | — | Source video to reframe (https URL or base64 data URI); up to 30s / 100MB. | | `aspect_ratio` | "1:1" \| "3:4" \| "4:3" \| "9:16" \| "16:9" \| "9:21" \| "21:9" | **yes** | — | Target aspect ratio; output is always 720p. | Example request body: ```json { "video_url": "https://example.com/clip.mp4", "aspect_ratio": "9:16" } ``` --- ### POST /v1/video/upscale Upscale a video to 1080p or 4K. - Input ≤ 30s, ≤ 100MB. Priced per 5 seconds of the source (rate depends on resolution × fps). Full spec (interactive): /docs#/Video/post_v1_video_upscale | field | type | required | default | description | |---|---|---|---|---| | `video_url` | string | **yes** | — | Source video to upscale (https URL or base64 data URI). | | `resolution` | "1080p" \| "4k" | no | `"1080p"` | Target output resolution. | | `frame_rate` | "30" \| "60" | no | `30` | Target output frame rate. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | Example request body: ```json { "video_url": "https://example.com/clip.mp4", "resolution": "4k", "frame_rate": 60 } ``` --- ### POST /v1/video/frames Generate a video that morphs a start image into an end image. - Tiers `frames-fast` (1080p, silent) / `frames-max` (1080p, optional audio). Full spec (interactive): /docs#/Video/post_v1_video_frames | field | type | required | default | description | |---|---|---|---|---| | `start_image_url` | string | **yes** | — | Start frame (https URL or base64 data URI) the video morphs from. | | `end_image_url` | string | **yes** | — | End frame (https URL or base64 data URI) the video morphs to. | | `prompt` | string | no | `""` | Optional text prompt guiding the morph. Max 2500 chars. | | `model` | string | no | `null` | Quality tier: frames-fast (1080p, silent) or frames-max (1080p, optional audio); null = default. | | `duration` | integer | no | `5` | Clip length in seconds. Allowed values depend on the model/tier and audio — see the capabilities block on GET /v1/products. | | `audio` | boolean | no | `false` | Generate native audio; requires frames-max. | Example request body: ```json { "start_image_url": "https://example.com/a.jpg", "end_image_url": "https://example.com/b.jpg", "model": "frames-max", "duration": 5 } ``` --- ### POST /v1/video/motion-control Animate the person in a photo with a reference video's motion. - Reference must show one clear, continuously-visible person (single shot, no cuts). - Reference 3–10s (≤ 30s when `character_orientation: "video"`), ≤ 100MB. Priced per second. - Reference width AND height must both be 340–3850px. Undersized videos are upscaled automatically so the call still succeeds — but upscaling cannot add detail, so send the highest resolution you have. Note for mobile apps: iOS often re-encodes videos picked from the photo library down to ~320px wide, below this floor. Export at native resolution (e.g. request the original asset rather than a transcoded copy) to avoid the quality loss. Full spec (interactive): /docs#/Video/post_v1_video_motion-control | field | type | required | default | description | |---|---|---|---|---| | `image_url` | string | **yes** | — | Character image to animate (https URL or base64 data URI). | | `video_url` | string | **yes** | — | Reference video supplying the motion (https URL or base64 data URI). | | `prompt` | string | no | `""` | Optional text prompt guiding the result. Max 2500 chars. | | `provider` | "vidom" | no | `"vidom"` | The Vidom engine. Pair with a `model` tier (e.g. `vidom-fast`). | | `model` | string | no | `null` | Model/tier name; null selects the provider default. | | `character_orientation` | "image" \| "video" | no | `"image"` | Whether the character's orientation follows the image or the reference video. | | `audio` | boolean | no | `true` | Generate native audio (where the model supports it). | Example request body: ```json { "image_url": "https://example.com/person.jpg", "video_url": "https://example.com/dance.mp4", "model": "motion-fast" } ``` --- ### POST /v1/video/avatar Generate a talking-head video from one photo and one audio file. - Output length follows the audio; priced per second. Input validated before charge. - Image: jpg/png, ≤ 10MB, ≥ 300px, aspect ratio 1:2.5–2.5:1. Audio: mp3/wav/m4a/aac, ≤ 5MB, 2–300s. Full spec (interactive): /docs#/Video/post_v1_video_avatar | field | type | required | default | description | |---|---|---|---|---| | `image_url` | string | **yes** | — | Image of the person to animate; jpg/png, <=10MB, >=300px, aspect ratio 1:2.5 to 2.5:1. | | `audio_url` | string | **yes** | — | Speech audio to perform; mp3/wav/m4a/aac, <=5MB, 2-300s. Output length and price follow the audio. | | `prompt` | string | no | `""` | Optional creative direction (actions, emotions, camera); auto-generated when omitted. | | `mode` | "std" \| "pro" | no | `"std"` | Quality mode: std (cost-effective) or pro (higher quality, 2x price). | Example request body: ```json { "image_url": "https://example.com/person.jpg", "audio_url": "https://example.com/speech.mp3", "mode": "std" } ``` ## Results ### GET /v1/video/:generationId Get the status and output of one generation (poll this). - `status` ∈ `pending` · `processing` · `completed` · `failed` · `cancelled`. - `output.url` is set once `completed` and is a permanent CDN URL (no expiry). While `processing`, `thumbnail_url` may already hold an early poster frame (vidom only). Full spec (interactive): /docs#/Video/get_v1_video__generationId --- ### DELETE /v1/video/:generationId Cancel a pending or processing generation. - Credits are **not** refunded — the job is already submitted to the provider. Full spec (interactive): /docs#/Video/delete_v1_video__generationId ## Inputs ### POST /v1/uploads Get a one-time upload URL for hosting a large input file. - Use this for inputs too big to inline as a data URI (large videos). Returns a presigned PUT `upload_url` (expires in 10 minutes) and a `file_url` to reference in a later generation. - Upload the raw bytes with `PUT`, matching the `Content-Type` and `Content-Length` you declared. Max 200MB. Requires a positive credit balance. Full spec (interactive): /docs#/Uploads/post_v1_uploads | field | type | required | default | description | |---|---|---|---|---| | `content_type` | "image/jpeg" \| "image/png" \| "image/webp" \| "image/heic" \| "image/gif" \| "video/mp4" \| "video/quicktime" \| "video/webm" \| "audio/mpeg" \| "audio/wav" \| "audio/mp4" \| "audio/aac" | **yes** | — | MIME type of the file you'll upload; must match the PUT's Content-Type header. | | `size` | integer | **yes** | — | Exact file size in bytes; must match the PUT's Content-Length. Max 200MB. | Example request body: ```json { "content_type": "video/mp4", "size": 5242880 } ``` ## Discovery ### GET /v1/products Live catalog + pricing + capabilities for every product. - Use this instead of hardcoding prices or option sets. Each entry has a `price` (credits) and a `capabilities` block (durations, audio, aspect ratios, resolutions, frame rates, input limits). Full spec (interactive): /docs#/Products/get_v1_products | query param | description | |---|---| | `feature` | Filter to one feature, e.g. `text-to-video`. | --- ### GET /v1/effects Browse the effect catalog for `POST /v1/video/effects`. - Each entry has a `key`, name, category, tags, preview media, and price. Supports `ETag` / `304`. Full spec (interactive): /docs#/Effects/get_v1_effects | query param | description | |---|---| | `category` | Filter by category. | | `tag` | Filter by tag. | --- ### GET /v1/styles Browse the style presets for the restyle endpoints. - Each entry has a `key`, name, category, preview media, and per-tier price. Supports `ETag` / `304`. Full spec (interactive): /docs#/Styles/get_v1_styles | query param | description | |---|---| | `category` | Filter by category. | --- ### GET /v1/credits Your remaining credit balance. - Returns `{ "credits": number }`. A call you can't afford is rejected with `402` and charges nothing, so pre-checking is optional. Full spec (interactive): /docs#/Account/get_v1_credits --- ## Webhooks (outbound — we call you) Include `webhook_url` on any create call. We POST JSON to it on state changes. **Trust the `status` field and treat the webhook as a signal to re-fetch;** only `generation.completed` and `generation.failed` are terminal. Delivery retries up to 3× with backoff; HTTPS only. Completed: ```json { "event": "generation.completed", "data": { "id": "gen_abc123", "type": "image-to-video", "status": "completed", "output": { "url": "https://cdn.vidom.ai/generations/acc_1/gen_abc123/output.mp4", "type": "video/mp4" } } } ``` Failed: ```json { "event": "generation.failed", "data": { "id": "gen_abc123", "status": "failed", "error": { "code": "provider_error", "message": "..." } } } ``` Preview-ready (non-terminal, `provider=vidom` only — a poster frame before the video finishes): ```json { "event": "generation.processing", "data": { "id": "gen_abc123", "status": "processing", "thumbnail_url": "https://cdn.vidom.ai/..." } } ``` --- ## Errors ```json { "error": { "code": "insufficient_credits", "message": "Not enough credits" } } ``` Common codes: `validation_error` (400), `invalid_request` (400), `unauthorized` (401), `forbidden` (403), `not_found` (404), `insufficient_credits` (402), `rate_limited` (429), `internal` (500). Input-validated features (edit, restyle-video, reframe, upscale, avatar, motion-control) reject bad input (unreachable / oversized / out-of-range media) with a `400` **before** charging — a rejected call costs nothing. --- ## Feature cheat sheet Pick a tier — Vidom routes it to the best engine for you (and can change the engine over time without changing your integration). | feature | tiers / options | |---|---| | text-to-video, image-to-video | vidom-fast / vidom-max (+audio) | | image | flat price; optional `sync` | | image restyle | preset styles (see `/v1/styles`); synchronous | | edit, video restyle | edit-fast / edit-max (restyle: fast / max) | | reframe | 7 aspect ratios, 720p | | upscale | 1080p / 4k × 30 / 60fps | | frames | frames-fast / frames-max (+audio) | | motion-control | motion-fast / motion-max | | avatar | std / pro | | extend | vidom-fast / vidom-max | | effects | ~297 named effects (see `/v1/effects`) | --- ## Also available - **Swagger UI**: `/docs` (browsable, try-it-out). - **OpenAPI JSON**: `/openapi.json` (machine-readable spec, generated from the live schemas — good for codegen). - **This file**: `/llms.txt` — generated from the same schemas that validate requests, so it stays in sync with the API.