> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.videogen.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.videogen.io/_mcp/server.

# Run a workflow

> Step one of the VideoGen flow: start a workflow with POST /v1/workflows/*, then poll the run until the video is ready.

A workflow runs the full generation pipeline and creates a VideoGen project. This is the first step of every video. Pick the workflow that matches your input, start it with one call, then wait for the run to finish.

| Workflow           | Input                        | Endpoint                                |
| ------------------ | ---------------------------- | --------------------------------------- |
| Script to video    | A script                     | `POST /v1/workflows/script-to-video`    |
| Voiceover to video | An uploaded audio file       | `POST /v1/workflows/voiceover-to-video` |
| Slideshow to video | An uploaded PDF or slideshow | `POST /v1/workflows/slideshow-to-video` |

## Start and wait

Start the workflow, then poll the run until `status` is terminal. The SDK helpers `pollWorkflowRun` (TS) and `poll_workflow_run` (Python) loop for you.

#### TypeScript

```typescript
import { VideoGen, pollWorkflowRun } from "@videogen/sdk";

const client = new VideoGen({ apiKey: "sk_videogen_live_..." });

const { workflowRunId, projectId } = await client.workflows.scriptToVideo({
  script:
    "Staying hydrated keeps your body and mind running at their best. Drinking enough water boosts your energy, focus, and mood. Keep a water bottle nearby and sip throughout the day.",
  visualStyle: {
    type: "AI_IMAGE",
    aiStyle: "Loose watercolor illustration, visible brushstrokes, soft color bleeds, paper texture, muted palette. A clear uncluttered subject centered in the frame, occupying only the middle half of the image, with generous empty margins on all four sides, no background clutter.",
  },
  quality: "HIGH",
  autoExport: true,
  remixActions: [
    { type: "ENABLE_CAPTIONS" },
    {
      type: "CONVERT_IMAGES_TO_VIDEOS",
      motionPrompt: "slow cinematic push-in",
      muteOutputVideos: true,
      quality: "HIGH",
    },
  ],
});

const run = await pollWorkflowRun({ client, workflowRunId });
console.log(run.downloadUrl);
```

#### Python

```python
from videogen import VideoGen, poll_workflow_run

client = VideoGen(api_key="sk_videogen_live_...")

response = client.workflows.script_to_video(
    script=(
        "Staying hydrated keeps your body and mind running at their best. "
        "Drinking enough water boosts your energy, focus, and mood. "
        "Keep a water bottle nearby and sip throughout the day."
    ),
    visual_style={
        "type": "AI_IMAGE",
        "ai_style": "Loose watercolor illustration, visible brushstrokes, soft color bleeds, paper texture, muted palette. A clear uncluttered subject centered in the frame, occupying only the middle half of the image, with generous empty margins on all four sides, no background clutter.",
    },
    quality="HIGH",
    auto_export=True,
    remix_actions=[
        {"type": "ENABLE_CAPTIONS"},
        {
            "type": "CONVERT_IMAGES_TO_VIDEOS",
            "motion_prompt": "slow cinematic push-in",
            "mute_output_videos": True,
            "quality": "HIGH",
        },
    ],
)

run = poll_workflow_run(client, response["workflowRunId"])
print(run.get("download_url") or run.get("downloadUrl"))
```

#### cURL

```bash
# Start the workflow
curl -X POST https://api.videogen.io/v1/workflows/script-to-video \
  -H "Authorization: Bearer sk_videogen_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "script": "Staying hydrated keeps your body and mind running at their best. Drinking enough water boosts your energy, focus, and mood. Keep a water bottle nearby and sip throughout the day.",
    "visualStyle": {
      "type": "AI_IMAGE",
      "aiStyle": "Loose watercolor illustration, visible brushstrokes, soft color bleeds, paper texture, muted palette. A clear uncluttered subject centered in the frame, occupying only the middle half of the image, with generous empty margins on all four sides, no background clutter."
    },
    "quality": "HIGH",
    "autoExport": true,
    "remixActions": [
      { "type": "ENABLE_CAPTIONS" },
      {
        "type": "CONVERT_IMAGES_TO_VIDEOS",
        "motionPrompt": "slow cinematic push-in",
        "muteOutputVideos": true,
        "quality": "HIGH"
      }
    ]
  }'

# Poll for the result (replace the workflow run id)
curl https://api.videogen.io/v1/workflows/runs/vg_work_... \
  -H "Authorization: Bearer sk_videogen_live_..."
```

The start response returns immediately with `{ workflowRunId, projectId, projectUrl, remixActionIds }` and `202 Accepted`. With `autoExport: true`, poll `GET /v1/workflows/runs/{workflowRunId}` until `status` is `succeeded`, then use `downloadUrl` for the MP4. `projectId` is for later remix or a second export. `projectUrl` is optional: a link to open the project in the VideoGen editor for manual review (team members and project collaborators only; see [Workflows](/workflows#about-projectid-and-projecturl)).

## Choosing a visual style

Script and voiceover workflows accept a `visualStyle`: `{ type: "AI_IMAGE", aiStyle }` for AI-generated images, where `aiStyle` is a free-form description of the look (see [AI styles](/ai-styles) for example descriptions), `{ type: "STOCK" }` for stock footage, or `{ type: "AI_IMAGE", entityId }` to match a VISUAL\_STYLE entity's reference images.

## Next steps

* [Apply remix actions](/apply-remix-actions): Add music, a logo, or natural-language edits.
* [Workflows reference](/workflows): Every workflow input and option.
* [Handling async tasks](/handling-async-tasks): Poll or use webhooks for the result.