Skip to main content

Integration guide

Animate a still you already trust.

Image-to-video removes the hardest variable — what the scene looks like — and replaces it with a narrower one: how it should move. The reference frame does most of the work, which is why a weak reference is not something the prompt can rescue.

The challenge

The reference frame decides most of the result

Motion endpoints inherit everything from the first frame: composition, lighting, aspect ratio, artefacts. A soft or badly cropped reference produces a soft, badly cropped clip, and you pay video rates for it.

01

Aspect mismatch is quietly expensive

If the reference is 1:1 and you request a 16:9 clip, the endpoint has to letterbox, crop or stretch. Match the reference to the aspect_ratio or resolution you are asking for before you submit, not after you have paid for the take.

02

Some endpoints take a closing frame too

Where last_image_url is declared, supplying both ends gives a defined start and finish instead of an open-ended drift. Where it is not declared, sending it is a 400.

03

Motion fields exist only where the model declares them

movement_amplitude, camera_fixed, fps and duration_seconds appear per endpoint, and the schema marks which of them move the rate. There is no shared motion vocabulary underneath.

The approach

Lock the frame first, then spend once on motion

Do the still work on an image endpoint where an iteration costs cents, lock the frame, and only then pay for motion. Passing a committed spicy:// upload keeps the reference byte-identical across retries, so a rerun starts from exactly the same pixels.

The body is a create call with an image field. The tracking half is identical to any other media task.

POST /api/v1/jobs/createTask

POST /api/v1/jobs/createTask
Authorization: Bearer $SPICY_API_KEY
Idempotency-Key: 7b1f0c2e-9a4d-4f31-8c67-2b5e0d9a1c44
Content-Type: application/json
{
  "model": "<publisher>/<model>/image-to-video",
  "input": {
    "prompt": "Slow push-in, fabric moving in a light breeze",
    "image_url": "https://example.com/reference.png",
    "duration_seconds": 5,
    "resolution": "720p"
  },
  "callBackUrl": "https://example.com/hooks/spicyapi"
}

202 Accepted

HTTP/1.1 202 Accepted
Location: /api/v1/jobs/recordInfo?taskId=job_01k3m8x9q2z4v7n5p6r8s0t1w3

{
  "code": 200,
  "msg": "success",
  "request_id": "req_example_create",
  "data": {
    "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "state": "queued",
    "estimatedCost": "0.750000"
  }
}

Contract

The parts worth pinning down

Image to video API: animate a still frame — The parts worth pinning down
Field or headerValue or limit
image_url · last_image_urldeclared per endpoint
POST /api/v1/jobs/retrynew task · source record untouched
statequeued · running · succeeded · failed · expired
audio / video upload≤ 100 MiB · ≤ 600 s

Swipe horizontally to see all columns.

Integration

From first call to production

  1. 01Produce or upload the reference frame at the aspect ratio you intend to render.
  2. 02Read the endpoint schema for image_url, duration_seconds, resolution and whichever motion fields it declares.
  3. 03Quote, then submit with an Idempotency-Key and a callback URL, and store the taskId with the reference.
  4. 04On a terminal callback, download output.assets and keep the reference beside the clip so a rerun is possible.

Fit

When this path is the right one

Choose this when

  • Art direction is already locked in a still and you want motion without re-rolling the scene.
  • The same character or product has to appear identically in every clip you ship.

Look elsewhere when

  • The scene does not exist yet. Iterating on stills is an order of magnitude cheaper than iterating on clips.
  • You need long-form continuity across many shots. These endpoints return short clips, one shot at a time.

Evidence

What you can verify yourself

Reference handling is identical everywhere

HTTPS URLs, committed spicy:// uploads and inline data URIs behave the same way across image and video endpoints, under the same limits and the same admission checks.

Retry creates a new task and never edits the old one

POST /api/v1/jobs/retry builds a fresh task from a failed or expired one and re-evaluates schema, price, permissions and availability. The source record stays exactly as it was.

One state machine covers the whole integration

queued, running, succeeded, failed, expired. The same five words describe every media endpoint, so you write the transition logic once.

Before launch

Platform behaviour to confirm

  • Match reference aspect ratio to the requested output before launch, not in support tickets.
  • Keep the reference reachable for the whole task lifetime, not just the moment of submission.
  • Give retries their own idempotency scope; a retry is a new task, not a replay of the old one.
  • Budget video rates into the daily key cap that every new key requires.

FAQ

Questions this page gets asked

That is your decision and your legal responsibility. The platform does not inspect uploads for identity, and the terms place consent and rights with the customer.

Keep going

Try an image-to-video endpoint

Turn a reference image into a clip. What first-frame quality, aspect mismatch, motion fields and duration do to the result and to the price.

Related guides