Kinoseed

Endpoints

Videos

One call starts a video run from a prompt, a start frame, an end frame or a set of reference images. Clips take minutes, so the job comes back at once and you follow it.

How it works

  • Pick a model from Models; each lists the inputs, aspects, durations and resolutions it takes. Without one the run uses seedance-1-5-pro.
  • duration is snapped to the nearest length the model can make. Longer clips, higher resolutions and audio: true cost more; POST /quote tells you how much.
  • startImageUrl and endImageUrl animate from or towards a frame; referenceImageUrls keeps a character or product consistent on models that take references. URLs must be public https, or come from POST /files.
  • The answer is a 201 job. Poll GET /jobs/{id}?wait=50 in a loop until it is completed; the clip is output.videoUrl, with a poster in output.thumbUrl.

Generate a video

post/api/v1/videos

Bearer keyvideos:generatecreateVideo

Start a video run. The price depends on the model, duration, resolution, sound and whether frames or reference images are sent; it is charged before the provider is called and refunded in full if the provider refuses. Needs videos:generate.

curl -X POST https://kinoseed.app/api/v1/videos \
  -H "Authorization: Bearer ks_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "slow push in on the mug as steam rises, morning light",
    "model": "kling-3",
    "duration": 5,
    "aspect": "16:9",
    "startImageUrl": "https://example.com/mug.png"
  }'

Parameters

NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoAny string of your choosing, up to 255 characters. A retry with the same key and body returns the first response (with Idempotent-Replayed: true) instead of starting and charging a second run. Kept for 24 hours.up to 255 characters

Request body

application/json

FieldTypeRequiredDescription
promptstringyesup to 2000 characters
modelstringnoA video model id from GET /models. Defaults to the catalog default.
aspectstringnoe.g. "16:9"
durationintegernoSeconds; snapped to the model's nearest allowed length.2 to 20
resolutionstringno
audiobooleannoGenerate sound. Off by default; it can double the price.
startImageUrlstring (uri)noPublic https URL, or a URL returned by this API.up to 2048 characters
endImageUrlstring (uri)noPublic https URL, or a URL returned by this API.up to 2048 characters
referenceImageUrlsstring (uri)[]noup to 9 items
seedintegerno
metadataRecord<string, string>noUp to 16 string values the caller wants back on the job.

Responses

StatusBodyMeaning
200JobThe provider refused the request at submission. The Job has status failed, error says why, and credits.refunded equals credits.charged: nothing was spent.
201JobThe video run was started and charged. Poll GET /jobs/{id} (or use ?wait=) until status is completed or failed.
400ErrorEnvelopeBody failed validation (invalid_request), the model is not in the catalog (unknown_model), or a URL is not public https (unsafe_url).
401ErrorEnvelopeMissing, invalid or revoked key.
402ErrorEnvelopeThe balance does not cover the quote; details has needed, balance and topUpUrl.
403ErrorEnvelopeThe key lacks the videos:generate scope.
409ErrorEnvelopeA request with this Idempotency-Key is still being processed.
422ErrorEnvelopeThis Idempotency-Key was already used with a different body.
429ErrorEnvelopeOver a rate budget; see Retry-After. Also too_many_running when the account already has 5 runs in progress.

Response fields

The 200 body.

FieldTypeDescription
idstring
kind"image" | "video"
statusJobStatus
progressinteger0 to 100
modelstring
promptstring
creditsobject
credits.chargedinteger
credits.refundedinteger
outputobject
output.videoUrlstring | null
output.imageUrlsstring[]
output.thumbUrlstring | null
errorstring | nullIn the customer's words; null unless failed.
metadataRecord<string, string> | null
createdAtstring (date-time)
completedAtstring (date-time) | null
linksobject
links.selfstring (uri)
links.webstring (uri)