loopling.ai

API reference

Create a video generation

Submit a prompt to start a video generation and reserve its Ink.

POST https://loopling.ai/v1/video/generations

Open in Playground

Authorization

Authorization

string · required

Your API key, as Bearer lpl_….

Headers

Idempotency-Key

string

Makes a retry return the first generation instead of starting another. 1–128 letters, digits, ., _, : or -.

Body · application/json

model

enum<string> · required

The model to run.

Available options: seedance-2.5, seedance-2.0, seedance-2.0-fast

prompt

string

What to generate. Up to 4,000 characters. Optional with a first frame or an image or video reference.

aspect_ratio

enum<string> · default: "16:9"

Frame shape. adaptive follows the first frame or the references.

Available options: 21:9, 16:9, 4:3, 1:1, 3:4, 9:16, adaptive

resolution

enum<string> · default: "720p"

Output resolution. Some models and aspect ratios cap it (unsupported_resolution).

Available options: 480p, 720p, 1080p

duration

integer · default: 5

Length in whole seconds. No "auto".

4–30 (seedance-2.5) · 4–15 (seedance-2.0, seedance-2.0-fast)

generate_audio

boolean · default: true

Adds a synchronised audio track. Included in the price.

seed

integer

-1 to 2147483647. Best-effort reproducibility, not guaranteed.

first_frame_url

string<uri>

Opening frame: a public https image.

last_frame_url

string<uri>

Closing frame. Needs first_frame_url.

reference_image_urls

string<uri>[]

Style and subject references.

≤ 30 (seedance-2.5) · ≤ 9 (seedance-2.0, seedance-2.0-fast)

reference_video_urls

string<uri>[]

Motion references.

≤ 10 (seedance-2.5) · ≤ 3 (seedance-2.0, seedance-2.0-fast)

reference_audio_urls

string<uri>[]

Sound references. On seedance-2.0 and seedance-2.0-fast, send an image or video beside them.

≤ 10 (seedance-2.5) · ≤ 3 (seedance-2.0, seedance-2.0-fast)

metadata

object

Your own JSON, up to 4 KiB. Echoed back in request.

Response · 202

id

string

Generation ID, vgen_….

object

enum<string>

Object type.

Available options: video.generation

status

enum<string>

succeeded and failed are final.

Available options: queued, running, succeeded, failed

progress

integer

0–100 while queued or running, when reported.

model

string

The model ID.

created_at

string<date-time>

When it was submitted.

completed_at

string<date-time>

When it reached succeeded or failed.

video

object

The clip. On succeeded, until the result expires.

url

string<uri>

Signed MP4 link. Needs no key; works until expires_at.

expires_at

string<date-time>

When url stops working. Read the generation again for a fresh link.

content_type

string

Always video/mp4.

duration_seconds

number

Seconds billed: the reported length, never more than requested, or the requested length when none is reported.

resolution

string

The requested resolution, or the default.

aspect_ratio

string

The requested aspect ratio, or the default. adaptive comes back as adaptive.

size_bytes

integer

File size in bytes.

result_expired

boolean

true once the clip is past retention. The record stays.

seed

integer

The seed used, when reported.

ink_reserved

integer

Ink held at submit: the most this generation can cost.

usd_payg_reserved

number

ink_reserved in pay-as-you-go USD.

ink_charged

integer

Ink charged, once final. 0 when failed.

usd_payg_charged

number

ink_charged in pay-as-you-go USD.

request

object

The request as accepted: defaults filled in, metadata inside.

error

object

Why it failed. On failed only.

code

string

The reason, such as provider_failed, timeout, result_persistence_failed, admission_failed or provider_rejected.

message

string

A sentence for your logs.

Request

curl

curl https://loopling.ai/v1/video/generations \
  -H "Authorization: Bearer $LOOPLING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.5",
    "prompt": "A paper lantern drifting over a night harbour, slow dolly in",
    "aspect_ratio": "16:9",
    "resolution": "1080p",
    "duration": 5
  }'

Node

const res = await fetch('https://loopling.ai/v1/video/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LOOPLING_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'seedance-2.5',
    prompt: 'A paper lantern drifting over a night harbour, slow dolly in',
    aspect_ratio: '16:9',
    resolution: '1080p',
    duration: 5,
  }),
})
const generation = await res.json() // { id: 'vgen_…', status: 'queued', ink_reserved, … }

Python

import os, requests

res = requests.post(
    "https://loopling.ai/v1/video/generations",
    headers={"Authorization": f"Bearer {os.environ['LOOPLING_API_KEY']}"},
    json={
        "model": "seedance-2.5",
        "prompt": "A paper lantern drifting over a night harbour, slow dolly in",
        "aspect_ratio": "16:9",
        "resolution": "1080p",
        "duration": 5,
    },
)
generation = res.json()  # {"id": "vgen_…", "status": "queued", "ink_reserved": …}

Response

202

{
  "id": "vgen_01J9X6K3M8Q2",
  "object": "video.generation",
  "status": "queued",
  "model": "seedance-2.5",
  "created_at": "2026-10-04T08:12:44Z",
  "ink_reserved": 320,
  "usd_payg_reserved": 3.2,
  "request": {
    "model": "seedance-2.5",
    "prompt": "A paper lantern drifting over a night harbour, slow dolly in",
    "aspect_ratio": "16:9",
    "resolution": "1080p",
    "duration": 5,
    "generate_audio": true
  }
}

400

{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_duration",
    "message": "duration must be an integer between 4 and 30 seconds for seedance-2.5",
    "param": "duration",
    "request_id": "0b7c6f1e-2d4a-4e8b-9c3f-5a1d7e2b8c40"
  }
}

401

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The API key is invalid, revoked or expired.",
    "request_id": "0b7c6f1e-2d4a-4e8b-9c3f-5a1d7e2b8c40"
  }
}

402

{
  "error": {
    "type": "insufficient_ink_error",
    "code": "insufficient_ink",
    "message": "This request needs 320 Ink but only 106 Ink is available. Top up in Inkwell and retry.",
    "request_id": "0b7c6f1e-2d4a-4e8b-9c3f-5a1d7e2b8c40"
  }
}

429

{
  "error": {
    "type": "rate_limit_error",
    "code": "concurrency_limit",
    "message": "At most 2 video generations may run at once on this account; wait for one to finish.",
    "request_id": "0b7c6f1e-2d4a-4e8b-9c3f-5a1d7e2b8c40"
  }
}

Answers 202 at once with a queued generation. Poll it for the result.

Frames and references

Start from frames or from references, not both (conflicting_references).

  • Frames. first_frame_url opens the shot. last_frame_url closes it and needs a first frame.
  • References. Images set style and subject, videos set motion, audio sets sound.

Caps per generation, by model:

ModelDurationResolutionsAspect ratiosReferences
seedance-2.54–30 s480p, 720p, 1080p21:9, 16:9, 4:3, 1:1, 3:4, 9:16, adaptive · 9:16, adaptive: up to 720p50: 30 images · 10 videos · 10 audio
seedance-2.04–15 s480p, 720p, 1080p21:9, 16:9, 4:3, 1:1, 3:4, 9:16, adaptive12: 9 images · 3 videos · 3 audio
seedance-2.0-fast4–15 s480p, 720p21:9, 16:9, 4:3, 1:1, 3:4, 9:16, adaptive12: 9 images · 3 videos · 3 audio

Over a per-kind cap answers too_many; over the total, reference_limit. seedance-2.0 and seedance-2.0-fast need an image or video beside any audio; seedance-2.5 takes audio alone.

Source URLs

Every frame and reference is a URL. Each must be:

  • https://, with no credentials in it;
  • at most 2,048 characters;
  • public when you submit.

Each URL is fetched once at submit. No copy is kept.

Retry safely

Send an Idempotency-Key. A retry with the same key returns the first generation: no second hold, no second render.

curl

curl https://loopling.ai/v1/video/generations \
  -H "Authorization: Bearer $LOOPLING_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: job-8812-lantern" \
  -d '{
    "model": "seedance-2.5",
    "prompt": "A paper lantern drifting over a night harbour, slow dolly in",
    "aspect_ratio": "16:9",
    "resolution": "1080p",
    "duration": 5
  }'

Node

const res = await fetch('https://loopling.ai/v1/video/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LOOPLING_API_KEY}`,
    'Content-Type': 'application/json',
    // Same key on every retry of this job: one hold, one render.
    'Idempotency-Key': 'job-8812-lantern',
  },
  body: JSON.stringify({
    model: 'seedance-2.5',
    prompt: 'A paper lantern drifting over a night harbour, slow dolly in',
    aspect_ratio: '16:9',
    resolution: '1080p',
    duration: 5,
  }),
})
const replayed = res.headers.get('Idempotent-Replayed') === 'true'

Python

import os, requests

res = requests.post(
    "https://loopling.ai/v1/video/generations",
    headers={
        "Authorization": f"Bearer {os.environ['LOOPLING_API_KEY']}",
        # Same key on every retry of this job: one hold, one render.
        "Idempotency-Key": "job-8812-lantern",
    },
    json={
        "model": "seedance-2.5",
        "prompt": "A paper lantern drifting over a night harbour, slow dolly in",
        "aspect_ratio": "16:9",
        "resolution": "1080p",
        "duration": 5,
    },
)
replayed = res.headers.get("Idempotent-Replayed") == "true"

Scope and edge cases: Idempotency.

Errors

Each 400 below names the field in param, except invalid_idempotency_key, which has none.

codeWhen
unknown_modelmodel isn't a listed ID.
invalid_enumresolution or aspect_ratio isn't a known value.
unsupported_resolutionThe model doesn't offer that resolution, or not at that aspect ratio.
invalid_durationduration isn't a whole number in the model's range.
unsupported_parameterduration is "auto" or -1.
invalid_typeA field has the wrong type.
too_longprompt is over 4,000 characters, a URL over 2,048, or metadata over 4 KiB.
invalid_urlA URL isn't https://, or carries credentials.
too_manyA reference list is over its per-kind cap.
reference_limitOver the model's total, or audio with no image or video.
conflicting_referencesFrames and references in one request.
missing_first_framelast_frame_url without first_frame_url.
missing_promptNo prompt, no first frame, and no image or video reference.
invalid_seedseed is outside -1 to 2147483647.
invalid_idempotency_keyThe Idempotency-Key header is malformed.

Auth, Ink and limit errors are in Errors.

Explore models

loopling.ai · grows with you, grows itself

hello@loopling.ai · for agents · community · pricing · Enterprise · API · privacy · terms