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.
Prerequisites
Step 1: Verify Your API Key
curl -X GET https://api.zvid.io/api/user/profile \
-H "x-api-key: YOUR_API_KEY"
Example response:
{
"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
curl -X GET https://api.zvid.io/api/credits/balance \
-H "x-api-key: YOUR_API_KEY"
{
"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 for the full preflight response.
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:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"queuePosition": 2,
"creditsReserved": 10
}
jobIdIt is the {id} used with the jobs endpoint in the next step.
Step 4: Poll the Render Job
curl -X GET https://api.zvid.io/api/jobs/{id} \
-H "x-api-key: YOUR_API_KEY"
Processing
{
"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
{
"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
{
"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 and
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:
Response fields
id: Render job ID.state: Job state —waiting,active,completed, orfailed.progress: Render/upload progress: a number or an object withphase,percentage, andmessage.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 benull.
Register a webhook or pass a per-request
webhookUrl and Zvid calls you when the job finishes.
Error Handling
Validation errors return 400 with field-level details:
{
"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
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.
- Design visually in the Editor.
- Automate with webhooks and bulk rendering.
- Browse the Examples.
- Share your first render or ask a question in the Zvid Discord community.