> This is the Markdown version of the Azimo developer docs page "Quickstart", for use by an AI assistant.
> - Azimo (https://azimo.ai) is an AI business-video production service: a brief and a few files in, a QA-checked commercial video out. It offers an asynchronous REST API, Python and TypeScript SDKs, the azimo command line and an MCP server.
> - Base URL: https://azimo.ai
> - Auth: every /v1 request sends `Authorization: Bearer <API key>` (create a key at https://azimo.ai/console#account); `X-Project-ID` selects a project, the default project otherwise.
> - This page: https://azimo.ai/en/developers/quickstart
> - Prices are not published: contact sales@azimo.ai.

# Quickstart

Go from an API key to your first submitted video in about five minutes: upload material, create a plan, start production, wait, and download the film.

## Plan first, then produce

A plan is free: it checks your request and freezes it. Only starting production from a plan uses your account balance.

So every film takes two calls. First `POST /v1/plans` and check that the plan is `ready`. When you are happy with it, `POST /v1/videos` to start production.

## Step 1: Get an API key

1. Sign in at [https://azimo.ai/console](https://azimo.ai/console). During the beta you need an invite code to register; email sales@azimo.ai to get one.
2. Open **Account → API Key** and create a key. It is shown only once, so copy it straight away.
3. Put it in an environment variable. Every example below uses it:

```bash
export AZIMO_API_KEY="your-api-key"
```

Send it on every request as `Authorization: Bearer $AZIMO_API_KEY`. Keep it out of your source code and your repository.

## Step 2: Walk through it with curl

**Upload a file (optional).** Accepted types: PDF, PPTX, TXT, MD, PNG, JPG, JPEG, WEBP, MP4, MOV, WEBM, MP3, WAV and M4A, up to 60 MB each.

```bash
curl -s https://azimo.ai/v1/assets \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Idempotency-Key: upload-brief-001" \
  -F "file=@brief.pdf"
```

The `id` in the response is the asset id, for example `"id": "744c8c43aa494843"`.

**Create a plan.** In the `prompt`, say what the film is about, who will watch it and what they should do afterwards.

```bash
curl -s https://azimo.ai/v1/plans \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: kettle-plan-001" \
  -d '{
    "prompt": "A 30-second product film for people who travel for work and stay in hotels: the Pliva Fold Kettle folds flat into a laptop bag, boils two cups at a time, and viewers should search for it in the official store.",
    "assets": ["744c8c43aa494843"],
    "options": {"workflow": "explainer", "duration_max": 30, "subtitles": true}
  }'
```

**Check the plan.** You can only produce a plan whose `data.status` is `ready`. If it is `needs_input`, `data.requirements` explains what is missing or unsupported; fix the request and create a new plan.

```json
{"id": "0bb27ba1d9d84b1a", "data": {"status": "ready", "requirements": [], "request": {"prompt": "…", "options": {"…": "…"}}}}
```

**Start production.** Send only the plan id. This is the step that uses your balance. It returns `202` and a video id.

```bash
curl -s https://azimo.ai/v1/videos \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: kettle-video-001" \
  -d '{"plan_id": "0bb27ba1d9d84b1a"}'
```

**Wait for it.** Production usually takes several minutes. Checking every 10 seconds or so is plenty:

```bash
curl -s https://azimo.ai/v1/videos/b6bf4689035d474f \
  -H "Authorization: Bearer $AZIMO_API_KEY"
```

The `status` moves through `queued` and `running`, then settles on one of these:

| Status | Meaning | What to do |
| --- | --- | --- |
| `complete` | The film passed its checks | Download it |
| `needs_input` | Azimo needs an answer or your approval to continue | Read `result.input_required`; see [Advanced usage](https://azimo.ai/en/developers/advanced) |
| `rejected` | The film did not pass the quality checks | Read `result.qa`, adjust, and produce again |
| `failed` / `cancelled` | Production failed or was cancelled | Read `error` |

**Download.** Once the video is `complete`, `result.files` holds signed download links: `film` is the MP4, and there may also be `srt` (subtitles) and `cover` (a still image). The links work without your key:

```bash
curl -L -o film.mp4 "<the link in result.files.film>"
```

Links expire. If one has expired, fetch the video again to get fresh links.

## The same flow with the Python SDK

You need Python 3.9 or later. See [CLI and MCP](https://azimo.ai/en/developers/cli-mcp) for installation: the `vidgen-sdk` package contains both the SDK and the `azimo` command.

```python
import os
from vidgen_sdk import Vidgen

with Vidgen("https://azimo.ai", os.environ["AZIMO_API_KEY"]) as azimo:
    asset = azimo.upload_asset("brief.pdf", idempotency_key="upload-brief-001")

    plan = azimo.create_plan({
        "prompt": "A 30-second product film for people who travel for work: the Pliva Fold Kettle "
                  "folds flat, boils two cups, and viewers should search for it in the official store.",
        "assets": [asset["id"]],
        "options": {"workflow": "explainer", "duration_max": 30, "subtitles": True},
    }, idempotency_key="kettle-plan-001")
    print(plan["data"]["status"], plan["data"]["requirements"])

    if plan["data"]["status"] == "ready":
        video = azimo.create_video(plan_id=plan["id"], idempotency_key="kettle-video-001")
        video = azimo.wait(video["id"], timeout=3600)  # also returns on needs_input
        if video["status"] == "complete":
            with open("film.mp4", "wb") as f:
                f.write(azimo.download_file(video["result"]["files"]["film"]))
        else:
            print(video["status"], video.get("result", {}).get("input_required"))
```

On any error the SDK raises `VidgenError`, which carries `status`, `code`, `message` and `request_id`.

## The same flow with the azimo command line

```bash
echo "$AZIMO_API_KEY" | azimo login        # checks the key, then saves it
azimo assets upload brief.pdf               # prints the asset id
azimo plan --prompt "A 30-second product film for hotel travellers about the Pliva Fold Kettle..." \
  --duration 30 --subtitles --asset 744c8c43aa494843
azimo create --plan 0bb27ba1d9d84b1a        # starts production (uses your balance)
azimo wait b6bf4689035d474f                 # waits; exit code 3 if it did not complete
azimo download b6bf4689035d474f --name all  # saves the film, subtitles and cover
```

`azimo plan` only creates a plan; it never starts production. See [CLI and MCP](https://azimo.ai/en/developers/cli-mcp) for more commands.

## Two good habits

- **Send an idempotency key on every write, and keep it.** Put your own value in the `Idempotency-Key` header. If a request times out, retry with the same key and you get the original result instead of a second film. The flip side: submitting the same plan again with a new key produces another video.
- **A timeout is not a failure.** Check the video's status before you submit anything again.

## Pricing and balance

Production uses your account balance. For pricing, contact sales@azimo.ai.

## Next steps

- [Workflows and video types](https://azimo.ai/en/developers/workflows): what each of the six film types needs and how to ask for it.
- [CLI and MCP](https://azimo.ai/en/developers/cli-mcp): use Azimo from a terminal or an AI assistant.
- [Advanced usage](https://azimo.ai/en/developers/advanced): webhooks, errors, rate limits, budget approval and revisions.
- [API reference](https://azimo.ai/en/developers/api): every endpoint and field.
