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

# Introduction

> Generate character animation videos with the Viggle API

<Tip>
  **Using an AI agent?** Copy the docs link for full API context:
</Tip>

```bash theme={null}
https://docs.viggle.ai/llms-full.txt
```

## Rendering modes

<Tabs>
  <Tab title="On-Demand" id="on-demand" icon="zap">
    Send an image + video in one request.

    <Tip>On-demand renders cost **1 credit/second** of output video. No separate character charge.</Tip>

    <CodeGroup>
      ```python Python theme={null}
      import requests, time
      API_KEY, BASE = "YOUR_API_KEY", "https://apis.viggle.ai"
      h = {"Authorization": f"Bearer {API_KEY}"}
      job = requests.post(f"{BASE}/api/render", headers=h, files={
          "ref_image": open("character.png", "rb"),
          "driving_video": open("dance.mp4", "rb"),
      }).json()
      while True:
          s = requests.get(f"{BASE}/api/render/{job['job_id']}").json()
          if s["status"] == "complete": break
          time.sleep(3)
      video = requests.get(s["cdn_url"])
      open("output.mp4", "wb").write(video.content)
      ```

      ```javascript JavaScript theme={null}
      const API_KEY = "YOUR_API_KEY", BASE = "https://apis.viggle.ai";
      const h = { Authorization: `Bearer ${API_KEY}` };
      const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
      const form = new FormData();
      form.append("ref_image", imageFile);
      form.append("driving_video", videoFile);
      const job = await fetch(`${BASE}/api/render`, { method: "POST", headers: h, body: form }).then((r) => r.json());
      let s;
      while (true) {
        s = await fetch(`${BASE}/api/render/${job.job_id}`).then((r) => r.json());
        if (s.status === "complete") break;
        await sleep(3000);
      }
      const video = await fetch(s.cdn_url);
      require("fs").writeFileSync("output.mp4", Buffer.from(await video.arrayBuffer()));
      ```

      ```bash cURL theme={null}
      curl -X POST "https://apis.viggle.ai/api/render" \
        -H "Authorization: Bearer YOUR_API_KEY" \
        -F "ref_image=@character.png" -F "driving_video=@dance.mp4"
      # Poll until status is "complete"
      curl "https://apis.viggle.ai/api/render/JOB_ID"
      # Download using cdn_url from the response
      curl -o output.mp4 "CDN_URL_FROM_RESPONSE"
      ```
    </CodeGroup>

    <Card title="On-Demand Guide" icon="zap" href="/guides/on-demand">
      Render options, polling, and error handling
    </Card>
  </Tab>

  <Tab title="Preprocessed" id="preprocessed" icon="rocket">
    Create character (1 credit) + scene (free) once, then render with IDs for lower latency.

    ```python theme={null}
    import requests
    API_KEY, BASE = "YOUR_API_KEY", "https://apis.viggle.ai"
    h = {"Authorization": f"Bearer {API_KEY}"}
    char = requests.post(f"{BASE}/api/characters/preprocess", headers=h,
        files={"image": open("character.png", "rb")}, data={"name": "My Character"}).json()
    scene = requests.post(f"{BASE}/api/scenes/preprocess", headers=h,
        files={"video": open("dance.mp4", "rb")}, data={"name": "Dance"}).json()
    job = requests.post(f"{BASE}/api/render", headers=h, data={
        "character_id": char["id"], "scene_id": scene["id"],
    }).json()
    ```

    <Card title="Preprocessing Guide" icon="rocket" href="/guides/quickstart">
      Polling, download, and asset reuse
    </Card>
  </Tab>

  <Tab title="Import Templates" id="import-templates" icon="download">
    Use templates from [viggle.ai](https://viggle.ai) instead of uploading a driving video.

    ```python theme={null}
    import requests
    API_KEY, BASE = "YOUR_API_KEY", "https://apis.viggle.ai"
    h = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
    scene = requests.post(f"{BASE}/api/scenes/import", headers=h,
        json={"template_uuid": "TEMPLATE_UUID_FROM_VIGGLE"}).json()
    ```

    <Card title="Import Templates Guide" icon="download" href="/guides/import-templates">
      Hot Picks, multi-person templates, character mapping
    </Card>
  </Tab>
</Tabs>

## Model

`V3_Preview` (default) or `V4_Preview`. Pass `model` on character preprocess, scene preprocess, and render requests. Characters and scenes are bound to the model they were preprocessed with and can only be used in renders with the same model.

## Quick start

<Steps>
  <Step title="Get your API key" icon="key">
    Create one in the [Viggle Dashboard](https://portal.viggle.ai/keys).
  </Step>

  <Step title="Pick a mode" icon="list">
    Use the **Rendering modes** tabs: **On-Demand** (fastest first render), **Preprocessed** (\~3x faster at scale), or **Import Templates**.
  </Step>

  <Step title="Render" icon="film">
    `POST /api/render` -- poll `GET /api/render/{job_id}` every 3-5s until `complete`, then use `cdn_url` to download.
  </Step>
</Steps>

## Resources

<Columns cols={3}>
  <Card title="Discord Community" icon="users" href="https://discord.com/invite/viggle">
    Support and discussions
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/render/overview">
    Full endpoint documentation
  </Card>

  <Card title="Pricing" icon="credit-card" href="/pricing">
    1 credit/sec -- about \$0.01/sec
  </Card>
</Columns>
