Developers

Video API

One POST turns a sentence into a short film with native audio. It runs on our own GPU, not a reseller account: MiniMax H3, 20 steps, no distilled shortcut. Billed by the second of finished video — $0.08 a second, and nothing else.

Three steps

1

Get a key

Sign in, open your account page, create an API key. It is shown once — save it. The same key works for the Director API.

2

Top up

Credits are prepaid on the same page. 1 credit = $0.01. Nothing expires.

3

Call it

POST a prompt, get a job_id back immediately, poll until it is done. Rendering takes minutes — write it as a job, not as a request.

Go to my account Try it in the browser first

What it costs

Eight credits per second of finished video. No per-request fee, no resolution tiers, no charge for a failed render.

LengthCreditsRoughlyRender time
4 s32$0.32about 3 min
8 s64$0.64about 8 min
10 s80$0.80about 10 min
15 s120$1.20about 17 min

All three modes cost the same. A reference render is about 25 seconds of extra setup — a fixed cost, not a multiplier — which is 10% of a 4-second clip and 2% of a 15-second one, so charging a premium for it would be inventing a number. Credits are held when you submit and become the charge on success. A failed or cancelled job is refunded in full, same minute. Render times are measured on our current card and are estimates, not promises — the number that matters is deliver_by in the response.

Three ways to make a clip

Same model, same price, same endpoint — mode picks which one you get.

modeWhat it doesWhat you send
textWords in, film out. The default; omit mode and you get this.prompt
animateA photo starts moving. Give a first frame; add a last frame and it moves between the two.first_frame, optional last_frame
castPut a specific person, object or look in the shot. Point at them in the prompt as <Picture 1>, <Picture 2>.ref_images: 1 to 4 images

GET /v1/models tells you which modes are open right now. We turn them on one at a time; a mode that is not open returns mode_unavailable rather than pretending.

How long it takes, honestly

Submit a job

curl -X POST https://spaceskills.shop/v1/videos \
  -H "Authorization: Bearer $SPACESKILLS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-clip-0001" \
  -d '{
    "prompt": "A red paper boat drifting on a calm pond at sunrise, soft golden light, gentle ripples on the water, slow push-in, cinematic",
    "duration_sec": 5
  }'
HTTP/1.1 202 Accepted
{
  "job_id": "vid_8Qk2ZrX1c0Nn",
  "status": "queued",
  "model": "h3/768p",
  "duration_sec": 5,
  "credits_held": 40,
  "balance": 460,
  "queue_position": 2,
  "est_render_sec": 168,
  "deliver_by": "2026-09-09T14:31:07.000Z",
  "poll": "/v1/videos/vid_8Qk2ZrX1c0Nn"
}

Returns 202 with a job_id and the credits held. Send an Idempotency-Key and a retried POST returns the same job instead of charging twice.

curl https://spaceskills.shop/v1/videos/vid_8Qk2ZrX1c0Nn \
  -H "Authorization: Bearer $SPACESKILLS_API_KEY"
{
  "job_id": "vid_8Qk2ZrX1c0Nn",
  "status": "succeeded",
  "duration_sec": 5,
  "seed": 774512900183,
  "credits_held": 0,
  "credits_charged": 40,
  "output": {
    "url": "https://media.spaceskills.shop/relay/vid_8Qk2ZrX1c0Nn.mp4",
    "stored": true
  },
  "error": null,
  "created_at": "2026-09-09T14:21:44.910Z",
  "updated_at": "2026-09-09T14:25:12.338Z"
}

status is one of queued, running, succeeded, failed, cancelled. On succeeded, output.url is the finished MP4 with audio muxed in.

Sending images

Same shape as the Director API: each image is inline base64 or an https URL we fetch.

# cast: put a specific face, object or look in the shot
curl -X POST https://spaceskills.shop/v1/videos \
  -H "Authorization: Bearer $SPACESKILLS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "cast",
    "prompt": "The woman from <Picture 1> walks slowly through a rainy neon street at night, reflections on wet asphalt, rain and distant traffic, slow tracking shot",
    "duration_sec": 6,
    "ref_images": [
      { "name": "her.jpg", "url": "https://example.com/her.jpg" }
    ]
  }'

# animate: start from a photo
curl -X POST https://spaceskills.shop/v1/videos \
  -H "Authorization: Bearer $SPACESKILLS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "animate",
    "prompt": "The lake ripples as the sun sinks lower, drifting clouds, distant birdsong, slow push-in",
    "duration_sec": 5,
    "first_frame": { "name": "lake.jpg", "url": "https://example.com/lake.jpg" }
  }'

Endpoints

EndpointWhat it does
GET /v1/modelsCatalogue: length range, price per second, current queue depth. Free, no key needed.
POST /v1/videosSubmit a prompt. Holds credits, returns job_id.
GET /v1/videos/{id}Status, and the file once it is ready.
GET /v1/videosYour last 30 jobs and your balance. Useful for reconciliation.
POST /v1/videos/{id}/cancelCancel while still queued. Full refund. Once it is running the GPU time is already spent, so it cannot be cancelled.

Request fields

FieldTypeNotes
promptstringWhat the shot should show. 8 to 20000 characters. Subject, motion, setting, light, camera — in that order works well.
duration_secinteger4 to 15. This is the pricing basis. Defaults to 5.
modestringtext, animate or cast. Defaults to text.
first_framefileanimate only, required. The frame the clip starts on.
last_framefileanimate only, optional. The frame it ends on.
ref_imagesfile[]cast only, 1 to 4. Refer to them in the prompt as <Picture 1> onwards, in the order you sent them.
modelstringDefaults to h3/768p, currently the only active model.
seedintegerOptional. Same seed, prompt and images reproduce the same clip. Omit it and one is drawn and echoed back on the job.

Headers: Authorization: Bearer sk_live_… and, recommended, Idempotency-Key: <any string you generate>. A key is remembered per account, so a network retry can never buy the same clip twice.

What comes back

The same job object from submit, poll and list — only the fields that are known yet are filled in.

Writing a prompt that works

The model reads plain prose, English or Chinese. It rewards specificity and punishes lists of adjectives.

Browse the prompt library

When things go wrong

CodeMeans
unauthorizedMissing or wrong key. Use Authorization: Bearer sk_live_…
insufficient_creditsBalance below the price. The response tells you both numbers.
bad_paramsNo prompt, prompt too long, or duration_sec outside 4–15.
unknown_modelNo such active model. Check GET /v1/models.
mode_unavailableThat mode is not open yet. The response lists the ones that are.
bad_materialAn image was too large, not a real JPEG/PNG/WebP, unreachable, or not https. The message says which slot.
payload_too_largeThe request body is over 24 MB. Send images as https URLs instead of inline base64.
model_unavailableNo render backend right now — usually a machine swap. Retry in a few minutes; nothing was charged.
capacity_deadline_infeasibleThe queue is deeper than six hours. Retry later; nothing was charged.
idempotency_conflictThat Idempotency-Key is in use by a different request body.
not_cancellableThe job is already running or finished.
rate_limitedToo many requests. Retry-After says how long to wait.

Limits

Looking for the Director API — brief and material in, a shot-by-shot plan out? That is documented here

Questions, or something behaving oddly? Tell us