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

# Quickstart

> Render a scene end-to-end with curl in under five minutes.

This walkthrough goes from "no key" to a downloaded MP4 using nothing but `curl`. If you'd rather see typed examples, the [API reference](/api-reference/introduction) ships per-endpoint snippets in JavaScript and Python.

<Steps>
  <Step title="Create an API key">
    Open the [developer dashboard](https://kodisc.com/developer/keys), click **New key**, give it a name, and copy the `kdsc_live_…` value. The plaintext is only shown once — store it somewhere safe.

    Want details on key format, rotation, and the optional default webhook URL? See [Authentication](/authentication).
  </Step>

  <Step title="Enqueue a render">
    `POST` your Manim code to `/api/v2/render`. The response is immediate — you get a `jobId`, not a video.

    ```bash theme={"system"}
    export KODISC_KEY="kdsc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

    curl -sS https://kodisc.com/api/v2/render \
      -H "Authorization: Bearer $KODISC_KEY" \
      -H "Content-Type: application/json" \
      -d @- <<'JSON'
    {
      "code": "from manim import *\n\nclass HelloKodisc(Scene):\n    def construct(self):\n        self.play(Write(Text(\"Hello, Kodisc\")))\n        self.wait(1)\n",
      "className": "HelloKodisc",
      "quality": "medium",
      "aspectRatio": "16:9"
    }
    JSON
    ```

    ```json Response (202) theme={"system"}
    {
      "jobId": "clx9f0a1b0000abcd1234efgh",
      "status": "queued",
      "endpoint": "render"
    }
    ```
  </Step>

  <Step title="Poll until it's done">
    Hit `GET /api/v2/render/{jobId}` every few seconds. When `status` flips to `completed`, the `result` object is populated.

    ```bash theme={"system"}
    curl -sS https://kodisc.com/api/v2/render/clx9f0a1b0000abcd1234efgh \
      -H "Authorization: Bearer $KODISC_KEY"
    ```

    ```json Response (200) theme={"system"}
    {
      "jobId": "clx9f0a1b0000abcd1234efgh",
      "endpoint": "render",
      "status": "completed",
      "creditsCost": 42,
      "durationMs": 18420,
      "result": {
        "video": "https://cdn.kodisc.com/r/clx9f0a1b0000abcd1234efgh/video.mp4",
        "thumbnail": "https://cdn.kodisc.com/r/clx9f0a1b0000abcd1234efgh/thumb.jpg",
        "captions": "https://cdn.kodisc.com/r/clx9f0a1b0000abcd1234efgh/captions.vtt"
      },
      "error": null,
      "metadata": null,
      "createdAt": "2026-04-28T17:14:02.118Z",
      "completedAt": "2026-04-28T17:14:20.539Z"
    }
    ```

    <Tip>
      In production, prefer [webhooks](/webhooks) to polling. Set `webhookUrl` once on the key and forget about it.
    </Tip>
  </Step>

  <Step title="Use the assets">
    The URLs in `result` are public and ready to embed, hot-link, or download.

    ```bash theme={"system"}
    curl -O https://cdn.kodisc.com/r/clx9f0a1b0000abcd1234efgh/video.mp4
    ```

    Need to know how much you have left to spend? `GET /api/v2/me` returns the current credit balance.
  </Step>
</Steps>

## What to read next

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/webhooks">
    Replace polling with a single signed POST per terminal state.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/errors">
    `400`, `401`, `402`, `404` — what each one means and how to recover.
  </Card>
</CardGroup>
