API documentation
One REST surface for 55 models. Every endpoint takes a JSON body and a bearer token, and returns the same envelope.
Quickstart
Create a key in the dashboard, export it, and call any model by slug.
export VIDDLY_API_KEY=vd_live_...
curl -X POST https://api.viddly.io/v1/video/generations \
-H "Authorization: Bearer $VIDDLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3-turbo",
"prompt": "a lighthouse in a storm, drone orbit, dusk",
"duration": 5
}'Authentication
Send your key as a bearer token. Keys are scoped per environment and can be revoked instantly from the dashboard. Never ship a key to a browser — proxy through your own backend.
Authorization: Bearer vd_live_9f3c…Async jobs & webhooks
Video and music renders return a job immediately. Poll the job, or pass webhook_url and we will POST the finished payload once.
// 1. submit
{ "id": "job_9f3c", "status": "queued", "model": "veo-3-1" }
// 2. poll
GET https://api.viddly.io/v1/jobs/job_9f3c
// 3. completed
{
"id": "job_9f3c",
"status": "completed",
"output": { "url": "https://cdn.viddly.io/v/9f3c.mp4" },
"credits_charged": 2560,
"duration_ms": 94210
}Streaming text
Text models are OpenAI-compatible. Point your existing SDK at our base URL and streaming, tool calls and vision keep working.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.VIDDLY_API_KEY,
baseURL: "https://api.viddly.io/v1",
});
const stream = await client.chat.completions.create({
model: "claude-opus-4-6",
messages: [{ role: "user", content: "Summarise this changelog." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}Errors
Errors are typed and consistent across providers. Credits are only deducted for calls that produce output.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is missing or out of range. Nothing is charged. |
| 401 | invalid_api_key | The key is revoked, malformed or missing the Bearer prefix. |
| 402 | insufficient_credits | Your balance cannot cover the estimated cost of the call. |
| 429 | rate_limited | Too many concurrent requests. Retry with the delay in Retry-After. |
| 503 | upstream_unavailable | Every upstream region for this model is down. No credits deducted. |
Rate limits
Limits are on concurrency, not requests per minute: 4 concurrent jobs on Starter, 20 on Pro and 100 on Studio. Every response carries x-viddly-concurrency-remaining.