---
name: create-short-video
description: Create a short-form vertical video with Veedio from a prompt, an idea, a script or an article URL, poll it to completion, and optionally publish it to TikTok, Instagram Reels or YouTube Shorts. Use when someone asks for a short video, a TikTok, a Reel, a YouTube Short or a faceless video.
license: MIT
---

# Create a short video with Veedio

Veedio turns text into a finished vertical video: a script split into scenes, one
generated visual per scene, an ElevenLabs voiceover, word-timed burned-in captions
and a music bed ducked under the narration. Generation is asynchronous and takes a
few minutes.

Use whichever surface this environment has, in this order of preference:

1. **MCP tools** if a Veedio MCP server is connected (`create_video`,
   `get_video_status`, `list_videos`, `calculate_credits`, `publish_video`,
   `get_account`).
2. **The CLI** if a shell is available: `veedio create --prompt "..." --wait --json`.
3. **The REST API** otherwise: `POST https://www.veedio.co/api/v1/videos`.

All three are the same pipeline and the same credits.

## Authentication

An API key from **Settings → API keys** at https://www.veedio.co/settings/api, sent as
a header. There is no OAuth.

```
Authorization: Bearer vd_live_...
```

`x-api-key`, `x-veedio-api-key` and `key` are accepted too. Read the key from the
`VEEDIO_API_KEY` environment variable; never print it, and never write it into a
file you are editing.

## Pick the workflow first

The `workflow` field decides what `source` must contain.

| workflow | source | Use it when |
| --- | --- | --- |
| `prompt-to-video` | `text` | There is a brief: a topic plus a length, an audience or a tone. |
| `script-to-video` | `text` | The exact words to be spoken already exist. Line breaks are scene breaks. |
| `idea-to-video` | `text` | There is only a subject and the angle is ours to pick. |
| `article-to-video` | `url` | A link is the starting point. The page is **not** fetched; the URL is passed to the writer as text. |

## Create

```bash
curl -X POST https://www.veedio.co/api/v1/videos \
  -H "Authorization: Bearer $VEEDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "workflow": "prompt-to-video",
  "source": { "text": "A 30-second video about why the ocean is salty, fun and educational" },
  "title": "Why the ocean is salty",
  "voice": "adam",
  "captionStyle": "highlight",
  "musicTrack": "lofi",
  "visualStyle": "documentary",
  "aspectRatio": "9:16"
}'
```

Everything but `workflow` and `source` is optional:

- `voice`: `rachel` (default), `adam`, `bella`, `josh`, `elli`
- `captionStyle`: `bold-center` (default), `highlight`, `subtle`, `none`
- `musicTrack`: `uplifting` (default), `lofi`, `cinematic`, `trap`, `none`
- `visualStyle`: `cinematic` (default), `3d`, `anime`, `documentary`, `retro`
- `aspectRatio`: `9:16` (default), `1:1`, `16:9`
- `title`: up to 120 characters

The call answers `202` immediately. **The video is not in this response.**

```json
{
  "id": "8f1c0f2e-8a4d-4f2b-9e2c-2f1a0b7c9d31",
  "status": "queued",
  "creditsEstimated": 12,
  "url": "https://www.veedio.co/videos/8f1c0f2e-8a4d-4f2b-9e2c-2f1a0b7c9d31"
}
```

## Poll

`GET https://www.veedio.co/api/v1/videos/{id}` every few seconds — no faster; the rate
limit is 60 requests a minute per key. Stop when `status` is `ready` (use
`videoUrl`) or `failed` (read `error`). `scenes[]` fills in as the pipeline works,
so report progress from it rather than saying nothing for four minutes.

## Publish, if asked

```bash
curl -X POST https://www.veedio.co/api/v1/videos/$ID/publish \
  -H "Authorization: Bearer $VEEDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "platforms": ["tiktok"], "caption": "the one everyone missed" }'
```

The platform must already be connected in Settings, and a video already live on a
platform is refused — which makes this call safe to retry after a dropped
connection. Publishing costs no credits. Do not pass `"force": true` to retry; it
posts a second copy to a real audience.

## Credits

2 credits plus 2 per scene, so a five-scene short is 12 credits. Quote a job first
with `POST https://www.veedio.co/api/v1/credits/estimate` (`{ "sceneCount": 6 }`, or
an empty body for the default) — it charges nothing and returns the balance. If the
user has not agreed to a cost, quote before creating.

## What Veedio cannot do

Say so plainly rather than trying; each of these fails or produces something the
person did not ask for.

- No video or audio goes in. It does not caption existing footage, cut a podcast
  into clips, or edit a file you already have. One photo can open a video
  (`photoUrl`), and a PDF link is read as a source; nothing else is uploaded.
- No face swap and no voice cloning. A presenter avatar (`mediaType: "avatar"`)
  exists on Pro and Studio where the deployment has it configured.
- Videos run 30, 60, 90 or 180 seconds. Free accounts make up to 60; paid up to 180.
- Five voices, narrating in 29 languages (`language`); image prompts and stock
  searches stay in English.
- URLs are fetched and read: articles, YouTube transcripts, X and LinkedIn posts,
  Reddit threads, PDFs, TikTok and Instagram captions. A page that cannot be read
  fails the request rather than letting the model guess.
- No completion webhook — polling is the only way to know it finished.

## Errors

Every failure is `{ "error": { "code", "message" } }`. Branch on `code`:
`invalid_request` (400, the message names the field), `unauthorized` (401),
`insufficient_credits` (402 — nothing was charged), `not_found` (404), `conflict`
(409, e.g. publishing a video that is not ready), `rate_limited` (429, honour
`Retry-After`), `internal_error` (500, retrying is safe).

## References

- Docs: https://www.veedio.co/docs
- Endpoint reference: https://www.veedio.co/docs/api-reference
- Workflow guide, as markdown: https://www.veedio.co/docs/workflows/prompt-to-video.md
- MCP setup: https://www.veedio.co/mcp
- CLI: https://www.veedio.co/docs/cli

MIT licensed. Fork it and adapt it to your runtime.
