# Short-drama workflow API: from script to clips

> Turn a script into character sheets, a storyboard, first frames and video clips with one request. POST /v1/workflows/short-drama runs script analysis, storyboarding, images and video; each step is billed at its model's price.

Web version: https://bigmodel.io/docs/short-drama-workflow · Updated 2026-10-18

`POST /v1/workflows/short-drama` takes a script and runs these steps in order:

1. **Characters**: finds the people and animals in the script and describes how they look;
2. **Storyboard**: splits scenes into shots with framing, camera move, picture, dialogue and sound, then packs shots into clips that fit the video model's length limit;
3. **Character sheets**: one full-body reference image per character, so they look the same in every shot;
4. **First frames**: one image per clip, using the characters in it as references;
5. **Video clips**: each clip animated from its first frame. Dialogue and sound are in the clip prompt, and models with native audio produce sound directly.

The workflow is one async job: submit a script, get a workflow ID, then poll. Each step is an ordinary generation billed at its model's unit price and listed in the console's Logs; failed steps are free.

Prefer no code? See the no-code tools in the [AI short-drama solution](https://bigmodel.io/solutions/short-drama).

## Estimate the cost

```bash
curl https://bigmodel.io/v1/workflows/short-drama \
  -H "Authorization: Bearer $BIGMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"script": "SCENE 1. Convenience store, rainy night…", "max_segments": 6, "dry_run": true}'
```

```json
{"object": "quote", "workflow": "short_drama", "max_segments": 6, "estimated_cost_usd": 4.24}
```

The estimate assumes `max_segments` clips of typical length. You pay for the clips and seconds actually produced, which is usually less.

## Create a workflow

```bash [cURL]
curl https://bigmodel.io/v1/workflows/short-drama \
  -H "Authorization: Bearer $BIGMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: episode-01" \
  -d '{
    "script": "SCENE 1. Corner store, rainy night\nMIA (20, short hair, yellow raincoat) runs under the awning holding a soaked puppy.\nMIA: It is okay, we are home.",
    "style": "warm, cinematic, photoreal",
    "aspect_ratio": "9:16",
    "image_model": "qwen-image-2.1",
    "video_model": "seedance-2.0-fast",
    "max_segments": 6
  }'
```

```python [Python]
import os, time, requests

BASE = "https://bigmodel.io/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BIGMODEL_API_KEY']}"}

wf = requests.post(f"{BASE}/workflows/short-drama", headers={**HEADERS, "Idempotency-Key": "episode-01"}, json={
    "script": open("episode-01.txt", encoding="utf-8").read(),
    "style": "warm, cinematic, photoreal",
    "aspect_ratio": "9:16",
    "video_model": "seedance-2.0-fast",
    "max_segments": 6,
}).json()

while wf["status"] in ("queued", "running"):
    time.sleep(15)
    wf = requests.get(f"{BASE}/workflows/{wf['id']}", headers=HEADERS).json()
    print(wf["stage"], wf["progress"])

for seg in wf["segments"]:
    print(seg["title"], (seg["video"] or {}).get("url"))
print("total", wf["cost_usd"])
```

### Request fields

| Field | Default | Description |
|---|---|---|
| `script` | required | The script, up to 20,000 characters. Clear scene headings, characters, action and dialogue give a better storyboard. |
| `style` | empty | Visual style, e.g. "warm, cinematic, photoreal" or "anime". Added to character-sheet and first-frame prompts. |
| `aspect_ratio` | `9:16` | `9:16` (vertical), `16:9` or `1:1`. |
| `image_model` | `qwen-image-2.1` | Text-to-image model for character sheets and frames. `qwen-image-2.1` uses the character sheets as references, which keeps faces most consistent. |
| `video_model` | `seedance-2.0-fast` | Video model for clips; it must animate an image. Models that take reference images (the `seedance-2.0` family, `minimax-h3`) use both the first frame and the character sheets. |
| `resolution` | model default (usually `720p`) | Must be one the video model supports. |
| `audio` | model default | Native audio on or off, for models that have it. |
| `max_segments` | `6` | Most clips to make (1–20). Longer scripts stop after this many. |
| `stop_after` | `videos` | Stop early: `storyboard` (characters and storyboard only), `frames` (plus sheets and frames) or `videos` (everything). |
| `dry_run` | `false` | Return the estimate only. |

The `Idempotency-Key` header is optional; repeating a value returns the same workflow.

## Progress and results

`GET /v1/workflows/{id}` returns:

```json
{
  "id": "e5d2c392-…",
  "object": "workflow.short_drama",
  "status": "running",
  "stage": "videos",
  "progress": {"clips_done": 1, "clips_total": 2},
  "estimated_cost_usd": 0.60,
  "cost_usd": 0.21,
  "characters": [
    {"name": "Mia", "look": "20, short hair, yellow raincoat…", "image": {"task_id": "…", "status": "succeeded", "url": "https://bigmodel.io/v1/media/…"}}
  ],
  "segments": [
    {
      "index": 1, "title": "Shot 01 · wide", "scene": "Corner store, rainy night", "seconds": 4, "cast": ["Mia", "Puppy"],
      "picture": "Warm light spills from the store glass…",
      "video_prompt": "[Shot 1 | 00:00-00:04] …",
      "frame": {"task_id": "…", "status": "succeeded", "url": "https://bigmodel.io/v1/media/…"},
      "video": {"task_id": "…", "status": "running"}
    }
  ],
  "storyboard": {"visualTone": "…", "scenes": [ … ]}
}
```

| Field | Description |
|---|---|
| `status` | `queued`, `running`, `succeeded`, `failed`, `canceled`. |
| `stage` | `characters`, `storyboard`, `character_images`, `frames`, `videos`, `done`. |
| `characters[].image` | The character-sheet task. |
| `segments[].frame`, `segments[].video` | First-frame and clip tasks. `url` is a signed link valid for 24 hours; fetch again for a new one. |
| `storyboard` | The full storyboard (scenes and shots with framing, camera, picture, dialogue, cast), for your own edits. |
| `cost_usd` | Charged so far; grows as steps finish. |

One failed clip doesn't fail the workflow: a clip whose first frame failed is skipped and the rest continue. The workflow is `failed` only if every frame or every clip fails.

## Cancel

```bash
curl -X POST https://bigmodel.io/v1/workflows/{id}/cancel -H "Authorization: Bearer $BIGMODEL_API_KEY"
```

Finished steps stay charged; running generations are cancelled and free.

## Time and cost

| Step | Typical time | Priced |
|---|---|---|
| Characters, storyboard | 1–3 minutes | A small charge per round (usually under $0.05) |
| Character sheets, frames | 20–60 s each, in parallel | Image model price × images |
| Video clips | 1–5 minutes each, in parallel | Video model price per second × seconds |

## Join the clips into an episode

The workflow returns clips in order. Join them in any editor, or with ffmpeg:

```bash
# Download the segment videos in order as 01.mp4, 02.mp4 …
printf "file '%s'\n" *.mp4 > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy episode.mp4
```

## Troubleshooting

| Symptom | Fix |
|---|---|
| `400` script is required | `script` is empty. |
| `400` video_model must be a video model that animates an image | Pick an image-to-video model from [Models → Video](https://bigmodel.io/models?type=Video). |
| `402` | Your balance can't cover the estimate. Top up or lower `max_segments`. |
| `failed`, Script analysis failed | The script couldn't be parsed. Add scene headings, characters and action, then retry. |
| Characters change between shots | Use `qwen-image-2.1` as `image_model` and a video model that takes reference images; describe the look in `style`. |

## Related

- [Multimodal overview](https://bigmodel.io/docs/multimodal-overview)
- [Video generation](https://bigmodel.io/docs/video-generation)
- [Image generation](https://bigmodel.io/docs/image-generation)
- [Media task API reference](https://bigmodel.io/docs/api-media-tasks)
