API reference

One contract, seven endpoints

OpenAI-shaped, so most SDKs need only a base-URL change. Submit returns 202 immediately; poll the job id until it reaches a terminal state. The everything happens in one job id.

EndpointPurpose
POST /v1/videos Submit a job. Returns 202 with an id, or 429 + Retry-After when your concurrency bucket is full.
GET /v1/videos/{id} Poll. Advances the state machine, so poll steadily — an unpolled job is reclaimed.
GET /v1/models The masked catalogue. Aliases only; real upstream ids are never exposed.
GET /v1/usage Daily and monthly rollups at list price, split by resolution, duration and model.
GET /v1/capacity Live headroom for your own bucket plus hub_total. Check before submitting a burst.
GET /v1/billing/balance Plan, granted credit and consumed credit for hosted-key tenants.
GET /healthz Liveness, provider identities and a capacity snapshot. No auth required.

Submitting a job

Only model and a prompt (or image_url) are required. Everything else has a default. Bad input is rejected with 400 before a concurrency slot is reserved, so a malformed request never costs you capacity.

curl -X POST https://api.example.com/v1/videos \
  -H "Authorization: Bearer cl_15f19a4c7b2e..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.5",
    "prompt": "a paper boat crossing a rain puddle at dusk",
    "metadata": {
      "resolution": "1080p",
      "duration": 5,
      "fps": 24,
      "bit_depth": 10
    }
  }'
// 202 Accepted
{
  "id": "job_8f3c21a0",
  "object": "video.generation",
  "status": "queued",
  "stage": "generating",
  "route": ["generate"]
}

Polling to completion

# status: queued -> running -> succeeded | failed
# stage:  generating -> enhancing -> done
curl https://api.example.com/v1/videos/job_8f3c21a0 \
  -H "Authorization: Bearer cl_15f19a4c7b2e..."
{
  "id": "job_8f3c21a0",
  "status": "succeeded",
  "url": "https://.../job_8f3c21a0-1080p.mp4",
  "metadata": {
    "resolution": "1080p",
    "base_resolution": "480p",
    
    
    "output": { "bit_depth": 10,
                "codec": "h265",
                "container": "mp4" }
  },
  "usage": { "generation": 0.515,
             
             "total": 0.8593 }
}
Polling drives the state machine. Advancement happens on poll rather than on a background timer, so the identical code runs on a long-lived process and on a serverless runtime that cannot hold timers. A job left unpolled past the idle window is reclaimed and its slot released, so one abandoned client cannot wedge your capacity.

Key masking

Every Cliplus key is a hosted key. You create it on your dashboard, it is scoped to your account, and you can revoke it at any time without affecting anyone else.

Your key — cl_…

40 random hex characters, minted when you click Create key. Only a SHA-256 hash, a 9-character prefix and the last 4 characters are stored, so the plaintext exists exactly once — in the response that created it. Copy it then; it is never shown again.

You get: real revocation, per-key usage and spend attribution, and as many keys as you want — one per environment, one per project, whatever suits your setup.

The base URL is shared

Every account calls the same endpoint. There is no per-customer hostname to provision and no DNS to configure — the key in your Authorization header is what identifies you.

Upstream provider credentials live server-side and never reach the caller, so nothing in your key can be replayed against a vendor API directly.

Create your key on the dashboard, then follow the copy-paste examples in the API guide.

Errors

StatusCodeMeaning
400invalid_requestMissing prompt and image, or a duration/fps outside the accepted range. No slot is consumed.
400invalid_modelUnknown model alias.
401unauthorizedMissing, malformed or revoked key.
404not_foundUnknown job id or unrouted path.
429capacityYour bucket is full. Honour Retry-After.
500router_errorUnexpected fault. Upstream failures surface as a failed job, not a 500.

Models

Pass any of these in the model field. Switching models is a one-word change — the request and response shapes are identical across all of them.

ModelResolutionsBest for
seedance-2.5480p – 4KHighest fidelity, cinematic motion
seedance-2.0480p – 1080pBalanced quality and cost
seedance-2.0-fast480p – 1080pLower latency, iteration and previews
seedance-2.0-mini480p – 720pCheapest per second, high volume

Per-second pricing for every model and resolution is on the pricing page. Your dashboard shows your effective price after any discount applied to your account.