---
title: "Quick Start"
canonical_url: https://docs.zvid.io/docs/quick-start/
source: docs/quick-start.md
content_revision: 6338386a1dd87e4a
---

# Quick Start

Render your first video by verifying your API key, checking credits,
validating a JSON payload, submitting it, and polling until the video URL is ready.
For an AI assistant connection, see [AI assistants](https://docs.zvid.io/docs/ai-assistants/).

## Prerequisites

- A Zvid account
- An [API key](https://docs.zvid.io/docs/authentication/) from the [dashboard](https://app.zvid.io/api-keys)
- Sufficient credits for the render

## Step 1: Verify Your API Key

```bash
curl -X GET https://api.zvid.io/api/user/profile \
  -H "x-api-key: YOUR_API_KEY"
```

Example response:

```json
{
  "user": {
    "id": 123,
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "createdAt": "2025-09-01T00:00:00.000Z"
  },
  "credits": {
    "balance": 1164,
    "subscriptionCredits": 1164,
    "addonCredits": {
      "balance": 0,
      "totalEarned": 0,
      "totalSpent": 0
    }
  }
}
```

## Step 2: Check Your Credit Balance

```bash
curl -X GET https://api.zvid.io/api/credits/balance \
  -H "x-api-key: YOUR_API_KEY"
```

```json
{
  "balance": 1164,
  "subscriptionCredits": 1164,
  "addonCredits": {
    "balance": 0,
    "totalEarned": 0,
    "totalSpent": 0
  }
}
```

## Step 3: Validate and submit your first render

The complete request below renders a 10-second Full HD video for **10 credits**.
First send this same body to `POST /api/render/validate/api-key` to check it
for free. A successful validation returns `valid: true` and
`creditsRequired`; it does not create a job. Then send it to the render URL
shown below when you are ready to spend credits.
See [Validate and estimate](https://docs.zvid.io/docs/validate-and-estimate/) for the full preflight response.

```bash
curl -X POST https://api.zvid.io/api/render/api-key \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
      "name": "hello-zvid",
      "width": 1920,
      "height": 1080,
      "duration": 10,
      "frameRate": 30,
      "backgroundColor": "#000000",
      "visuals": [
        {
          "type": "TEXT",
          "text": "Hello, Zvid!",
          "x": 960,
          "y": 540,
          "anchor": "center-center",
          "style": {
            "fontSize": 72,
            "color": "#ffffff",
            "fontFamily": "Arial"
          }
        }
      ]
    }
  }'
```

Example response:

```json
{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "queuePosition": 2,
  "creditsReserved": 10
}
```

> **Save the `jobId`**
It is the `{id}` used with the jobs endpoint in the next step.

## Step 4: Poll the Render Job

```bash
curl -X GET https://api.zvid.io/api/jobs/{id} \
  -H "x-api-key: YOUR_API_KEY"
```

### Processing

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "state": "active",
  "progress": {
    "phase": "rendering",
    "percentage": 65,
    "message": "Rendering frames..."
  },
  "result": null,
  "failedReason": null,
  "ts": {
    "created": 1774290612835,
    "updated": 1774290615000,
    "finished": null
  }
}
```

### Completed

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "state": "completed",
  "progress": {
    "phase": "uploading",
    "percentage": 100,
    "message": "Uploading to B2: 100%"
  },
  "result": {
    "ok": true,
    "renderDuration": 16,
    "totalDuration": 17,
    "finishedAt": "2026-03-23T18:30:29.888Z",
    "url": "https://cdn.zvid.io/videos/4/hello-zvid.mp4",
    "thumbnailUrl": "https://cdn.zvid.io/images/4/hello-zvid_thumbnail.jpg",
    "size": 3848989,
    "fileName": "hello-zvid.mp4",
    "duration": 10
  },
  "failedReason": null,
  "ts": {
    "created": 1774290612835,
    "updated": 1774290612835,
    "finished": 1774290629888
  }
}
```

### Failed

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "state": "failed",
  "progress": {
    "phase": "rendering",
    "percentage": 40,
    "message": "Processing failed"
  },
  "result": null,
  "failedReason": "Rendering failed due to invalid asset",
  "ts": {
    "created": 1774290612835,
    "updated": 1774290617000,
    "finished": 1774290617000
  }
}
```

Poll every few seconds with a bounded timeout. When `state` is `completed`,
use `result.url`; when it is `failed`, inspect `failedReason` and stop polling.
A submission `jobId` identifies the job; the lookup response uses `id` and
`state`. Do not submit the render again merely because a poll failed.
See [Render lifecycle](https://docs.zvid.io/docs/operations/render-lifecycle/) and
[Errors and retries](https://docs.zvid.io/docs/operations/errors-and-retries/) for recovery.

This recorded preview shows the composition submitted in step 3. The response
URLs above are examples; use the `result.url` returned by your own job:


hello-zvid.mp4 — 1920×1080, 10 s

[Watch rendered example](https://cdn.zvid.io/library/docs/hello-zvid.mp4)


### Response fields

- `id`: Render job ID.
- `state`: Job state — `waiting`, `active`, `completed`, or `failed`.
- `progress`: Render/upload progress: a number or an object with `phase`, `percentage`, and `message`.
- `result`: Final render output when completed.
- `failedReason`: Error message when the job fails.
- `ts`: Created, updated, and finished Unix timestamps in milliseconds; unfinished timestamps can be `null`.

> **Prefer push over polling?**
Register a [webhook](https://docs.zvid.io/docs/automation/webhooks/) or pass a per-request
`webhookUrl` and Zvid calls you when the job finishes.

## Error Handling

Validation errors return `400` with field-level details:

```json
{
  "error": "Validation failed",
  "message": "Please check your input and try again",
  "details": [
    {
      "field": "payload.duration",
      "message": "Duration must be at least 0.1 seconds"
    }
  ]
}
```

Fix the listed fields and submit the request again. When a payload exceeds your
plan's limits, the error message includes the active limits.

## API base URL

```text
https://api.zvid.io
```

REST paths begin with `/api`, for example `/api/jobs/{id}`. Do not add a
second `/api` when using an SDK that already prefixes its routes.

## Next Steps

- Explore the [JSON Structure Overview](https://docs.zvid.io/docs/structure/).
- Design visually in [the Editor](https://docs.zvid.io/docs/editor/overview/).
- Automate with [webhooks](https://docs.zvid.io/docs/automation/webhooks/) and [bulk rendering](https://docs.zvid.io/docs/automation/bulk-rendering/).
- Browse the [Examples](https://docs.zvid.io/docs/examples/inspirational-video/).
- Share your first render or ask a question in the [Zvid Discord community](https://discord.gg/MZyWKqHDj3).
