> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lavendly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From zero to a rendered video in five minutes.

## 1. Get an API key

Sign up at <a href="https://lavendly.ai">lavendly.ai</a> and create
an API key from your dashboard. You'll use it in the `Authorization`
header on every request.

```bash theme={null}
export LAVENDLY_API_KEY=lv_live_…
export LAVENDLY_API=https://api.lavendly.ai
```

## 2. Render a video from a single prompt

The simplest possible call: a workflow with one shot, rendered server-side.

<CodeGroup>
  ```bash cURL theme={null}
  WF=$(curl -s -X POST $LAVENDLY_API/v1/workflows \
    -H "Authorization: Bearer $LAVENDLY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Bookshop fox",
      "shots": [
        { "prompt": "a sleepy fox in a bookshop discovering an old map",
          "duration": 5 }
      ]
    }' | jq -r .id)

  JOB=$(curl -s -X POST $LAVENDLY_API/v1/workflows/$WF/renders \
    -H "Authorization: Bearer $LAVENDLY_API_KEY" -d '{}' | jq -r .job_id)

  # Poll until done
  while :; do
    STATUS=$(curl -s $LAVENDLY_API/v1/workflows/$WF/renders/$JOB \
      -H "Authorization: Bearer $LAVENDLY_API_KEY" | jq -r .status)
    echo "$STATUS"
    [[ $STATUS == "done" || $STATUS == "failed" ]] && break
    sleep 4
  done

  curl -s $LAVENDLY_API/v1/workflows/$WF/renders/$JOB \
    -H "Authorization: Bearer $LAVENDLY_API_KEY" | jq .result.video_url
  ```

  ```js Node theme={null}
  import { Lavendly } from './lavendly.js';   // see /sdks/node
  const vs = new Lavendly({ apiKey: process.env.LAVENDLY_API_KEY });

  const wf = await vs.workflows.create({
    name: "Bookshop fox",
    shots: [{ prompt: "a sleepy fox in a bookshop", duration: 5 }],
  });

  const video = await vs.renders.run(wf.id);   // creates + polls until done
  console.log(video.url);
  ```

  ```py Python theme={null}
  from lavendly import Lavendly      # see /sdks/python
  vs = Lavendly(api_key=os.environ["LAVENDLY_API_KEY"])

  wf = vs.workflows.create(
      name="Bookshop fox",
      shots=[{"prompt": "a sleepy fox in a bookshop", "duration": 5}],
  )

  video = vs.renders.run(wf.id)
  print(video.url)
  ```
</CodeGroup>

## 3. Add a voiceover and a music bed

Once you have a workflow, attach extra tracks to a shot:

```bash theme={null}
# Voiceover with auto-generated captions
curl -X POST $LAVENDLY_API/v1/workflows/$WF/clips/shot_1/tracks \
  -H "Authorization: Bearer $LAVENDLY_API_KEY" \
  -H "Idempotency-Key: vo-$WF" \
  -d '{
    "kind": "voiceover",
    "script": "Once upon a time, in a quiet bookshop...",
    "subtitleStyle": "tiktok"
  }'

# Music bed with auto-ducking under the voiceover
curl -X POST $LAVENDLY_API/v1/workflows/$WF/clips/shot_1/tracks \
  -H "Authorization: Bearer $LAVENDLY_API_KEY" \
  -H "Idempotency-Key: music-$WF" \
  -d '{ "kind": "music", "mood": "warm cozy ambient", "ducking": true }'
```

Re-render and you get the finished, mixed clip with burn-in captions.

## 4. Give an agent the same capability

Anything you just did with cURL, an agent can do through the
[agent skills](/agent-skills/overview) interface. The same operations
are exposed as tools; the same idempotency keys keep retries safe.

Try this prompt in any agent that's been wired up to Lavendly:

> Create a 5-second video of a fox in a bookshop, narrate it in a warm
> voice with captions, lay a cozy ambient track underneath, and send me
> the URL when it's done.

That's six tool calls and a render. No glue code on your side.

## What's next

<CardGroup cols={2}>
  <Card title="Wire an agent in" icon="robot" href="/agent-skills/overview">
    Two-minute setup for Claude Desktop, Cursor, and other agent runtimes.
  </Card>

  <Card title="Node SDK" icon="js" href="/sdks/node">  Cookbook patterns. </Card>
  <Card title="Python SDK" icon="python" href="/sdks/python">Cookbook patterns. </Card>

  <Card title="API reference" icon="book" href="/api-reference/overview">
    Every operation, response shape, and error code.
  </Card>
</CardGroup>
