API reference
Every endpoint and object of the Cuddler Platform API v1.
Base URL: https://api.cuddler.ai/v1 · Auth: Authorization: Bearer cud_sk_live_… · Format: JSON, snake_case
The live, machine-readable definition is the OpenAPI document at https://api.cuddler.ai/v1/openapi.json; a compact summary for coding assistants is at https://api.cuddler.ai/v1/llms.txt. If this page and the OpenAPI document ever disagree, the OpenAPI document wins.
Endpoints
| Method | Path | Test keys | Returns |
|---|---|---|---|
GET | /v1/models | Yes | A list of model objects |
GET | /v1/models/{id} | Yes | A model object |
POST | /v1/videos/estimate | Yes | An estimate object |
POST | /v1/videos | No | 202 and a video object |
GET | /v1/videos | No | A list of video objects |
GET | /v1/videos/{id} | No | A video object |
POST | /v1/videos/{id}/cancel | No | A video object |
POST | /v1/uploads | No | An upload object, with upload_url |
POST | /v1/uploads/{id}/complete | No | An upload object |
GET | /v1/uploads/{id} | No | An upload object |
GET | /v1/balance | Yes | A balance object |
GET | /v1/usage | Yes | A usage object |
Every response carries X-Request-Id. Errors use the error envelope.
Models
GET /v1/models
Lists the models, their capabilities and prices, with enabled saying whether your organization may use each one. Returns { "object": "list", "data": [model, …] }.
GET /v1/models/{id}
id is seedance-2.5, seedance-2.0 or seedance-2.0-mini (coming soon: listed with enabled: false until it launches). Returns a model object, or 404 not_found.
Videos
POST /v1/videos/estimate
Prices a planned job. Nothing is created or charged.
| Body field | Type | Notes |
|---|---|---|
model | string | Required. |
duration | integer | Required. 4–30, within the model's range. |
resolution | string | Default 720p. |
aspect_ratio | string | Default 16:9. |
input_video_seconds | number | Default 0, up to 300. Seconds of reference video the job will include. |
POST /v1/videos
Creates a video job. Header Idempotency-Key is required. The body fields are listed in Models and parameters. Answers 202 with the video (status is queued, already running when a slot was free, or already failed if it could not be submitted — the model refused it, or the submission was not confirmed: error.code says which; nothing is charged), or 200 with the original video and Idempotent-Replayed: true when the same key and body were already used.
GET /v1/videos
Lists your organization's videos, newest first.
| Query | Notes |
|---|---|
status | Optional: queued, running, succeeded, failed or canceled. |
limit | 1–100, default 20. |
cursor | next_cursor from the previous page. |
Returns { "object": "list", "data": [video, …], "next_cursor": string | null }.
GET /v1/videos/{id}
Returns the video. A fresh output.url is signed on every call.
POST /v1/videos/{id}/cancel
Cancels a queued video and releases its hold. Returns the video with status: "canceled", or 409 not_cancelable if it is no longer queued.
Uploads
POST /v1/uploads
Header Idempotency-Key is required.
| Body field | Type | Notes |
|---|---|---|
kind | string | image, video or audio. |
content_type | string | A supported type for the kind (Uploads). |
bytes | integer | The exact file size. |
filename | string | Optional, up to 200 characters. |
Returns the upload with upload_url and upload_headers: PUT the file there before expires_at.
POST /v1/uploads/{id}/complete
Checks and prepares the uploaded file. Returns the upload with status ready or rejected.
GET /v1/uploads/{id}
Returns the upload.
Account
GET /v1/balance
Returns the balance object.
GET /v1/usage
| Query | Notes |
|---|---|
from | Required. UTC date, YYYY-MM-DD, inclusive. |
to | Required. UTC date, inclusive; at most 366 days after from. |
Returns the usage object.
Objects
Video
| Field | Type | Notes |
|---|---|---|
object | "video" | |
id | string | vid_… |
status | string | queued, running, succeeded, failed or canceled |
model | string | |
prompt | string | |
duration | integer | Requested seconds |
resolution | string | |
aspect_ratio | string | |
generate_audio | boolean | |
created_at | string | ISO 8601 |
started_at | string or null | When rendering started |
completed_at | string or null | When the job reached a final state |
queue_position | integer or null | Jobs ahead in your queue (queued only) |
estimate | object | tokens, usd, hold_usd |
usage | object or null | tokens, usd, usd_micros (succeeded only) |
output | object or null | url, url_expires_at, retained_until, width, height, duration, has_audio, last_frame_url |
error | object or null | code, message (failed only) |
metadata | object | Your string pairs |
price_version | string | The price list the job is billed at |
api_key_id | string | The key that created the job |
Estimate
| Field | Type | Notes |
|---|---|---|
object | "estimate" | |
model, resolution, aspect_ratio, duration, input_video_seconds | Echo of the request | |
tokens | integer | Estimated tokens |
usd | string | Estimated charge |
usd_micros | integer | The same, in millionths of a dollar |
hold_usd | string | What a job would hold from the balance |
usd_per_second | string | 16:9 display figure |
price_version | string |
Upload
| Field | Type | Notes |
|---|---|---|
object | "upload" | |
id | string | upl_… |
kind | string | image, video or audio |
status | string | pending, ready, rejected or expired |
content_type | string | |
bytes | integer | |
upload_url | string | Only right after create |
upload_headers | object | Only right after create |
expires_at | string | Upload deadline while pending; deletion time once ready |
rejection_reason | string | Only when rejected |
created_at | string |
Model
| Field | Type | Notes |
|---|---|---|
object | "model" | |
id, display_name | string | |
min_duration, max_duration | integer | Seconds |
resolutions, aspect_ratios | array of strings | |
max_reference_images, max_reference_videos, max_reference_audios, max_references | integer | |
audio_only_reference | boolean | Whether an audio reference may be used on its own |
native_audio | true | |
enabled | boolean | For your organization |
pricing | array | Per resolution: usd_per_million_tokens, usd_per_million_tokens_with_video_input, usd_per_second |
price_version | string |
Balance
| Field | Type | Notes |
|---|---|---|
object | "balance" | |
currency | "usd" | |
total_usd, held_usd, available_usd | string | See Pricing and billing |
daily_limit_usd, spent_today_usd | string | UTC day |
expires_at | string or null | 12 months after the latest top-up |
Usage
| Field | Type | Notes |
|---|---|---|
object | "usage" | |
from, to | string | The requested range |
total | bucket | usd, tokens, seconds, videos_succeeded, videos_failed |
by_day | array | Buckets with date |
by_model | array | Buckets with model and resolution |
by_key | array | Buckets with api_key_id and api_key_name |
Event
| Field | Type | Notes |
|---|---|---|
object | "event" | |
id | string | evt_…, for de-duplication |
type | string | video.succeeded, video.failed, video.canceled, balance.low or balance.depleted |
created_at | string | |
data | object | A video object or a balance object |
Error
| Field | Type | Notes |
|---|---|---|
code | string | See the error codes |
message | string | |
details | any | Optional |
request_id | string | Matches X-Request-Id |