Edit Video
Edit a clip you generated from a prompt (outfit, style, lighting, props), or transfer a clip's motion onto the person in one of your images. Returns a task to poll.
Instruction edits. spicy-video-edit-1 ($0.20/s 720P, $0.30/s 1080P) takes 2 to 10 second clips, up to 4 reference images and an optional aspect_ratio; the output keeps the clip's length. spicy-cinema-1-edit ($0.28/s 720P, $0.48/s 1080P) takes 3 to 30 second clips and up to 5 reference images, and edits and returns the first 15 seconds. Both bill the input clip's seconds plus the output's: debited up front at the upper bound and settled to the seconds actually processed when the task finishes (the difference is refunded).
Motion transfer. spicy-animate-1 ($0.24/s standard, $0.36/s pro, per output second) makes the person in image_url perform the moves and expressions of a motion clip: pick one from GET /v1/videos/motions with motion, or pass one of your own clips of 2 to 30 seconds as video_url. The output is as long as the motion clip. Full-body images in the clip's framing work best. This model screens its inputs and outputs itself and refuses explicit or nude images and clips (the task fails with error_code: "blocked" and is refunded), so use a dressed performer.
Every input must come from your own account: video_url is the output.video_url of one of your finished tasks, images are from GET /v1/images. The prompt is screened like any other before anything is charged. Poll GET /v1/videos/tasks/{id} (the task's usage.input_seconds shows billed input seconds) or receive the same webhooks as video generation. GET /v1/models describes each model under video_edit.
# swap the outfit in one of your clips
curl --request POST \
--url https://api.spicyapi.com/v1/videos/edits \
--header 'Authorization: Bearer $SPICYAPI_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "spicy-video-edit-1",
"video_url": "https://cdn.spicyapi.com/outputs/a1b2/sj_9a2b3c4d.mp4",
"prompt": "she wears the red dress from Image 1, same room and lighting",
"reference_image_urls": ["https://cdn.spicyapi.com/outputs/a1b2/sj_2f1c7e9a-0.png"],
"resolution": "720P",
"keep_audio": true
}'
# motion transfer from the library
curl --request POST \
--url https://api.spicyapi.com/v1/videos/edits \
--header 'Authorization: Bearer $SPICYAPI_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "spicy-animate-1",
"image_url": "https://cdn.spicyapi.com/outputs/a1b2/sj_2f1c7e9a-1.png",
"motion": "mo_hip_dance",
"quality": "standard"
}'{
"id": "sj_7e1d4a9c2b6f8e0a3d5c7b9f",
"object": "task",
"type": "video",
"model": "spicy-video-edit-1",
"status": "queued",
"output": null,
"error": null,
"cost_usd": 2,
"poll_url": "/v1/videos/tasks/sj_7e1d4a9c2b6f8e0a3d5c7b9f"
}Body
application/jsonspicy-video-edit-1, spicy-cinema-1-edit or spicy-animate-1.
The clip: one of your own finished video outputs. Required on the instruction-edit models (2 to 10 seconds on spicy-video-edit-1, 3 to 30 on spicy-cinema-1-edit). On spicy-animate-1, the motion clip (2 to 30 seconds), or send motion instead.
Required on the instruction-edit models: the change to make, up to 5,000 characters. Refer to reference images as Image 1, Image 2. Not used by spicy-animate-1.
Instruction edits: outfit, prop or style images from your own library, up to 4 on spicy-video-edit-1 and 5 on spicy-cinema-1-edit. Not accepted on spicy-animate-1.
Instruction edits: 720P (default) or 1080P.
spicy-video-edit-1 only: reshape the output to 16:9, 9:16, 1:1, 4:3 or 3:4. Omit to keep the clip's shape.
Instruction edits: true keeps the clip's original soundtrack.
Instruction edits: what to avoid.
Instruction edits: reproducibility seed.
spicy-video-edit-1 only: let the model expand the prompt before editing.
spicy-animate-1 only, required: the person who performs the motion, one of your generated images.
spicy-animate-1 only: a motion id from GET /v1/videos/motions (mo_slow_sway, mo_hip_dance, mo_hair_turn, mo_catwalk, mo_wave), instead of video_url.
spicy-animate-1 only: standard (default) or pro, priced separately.
When true, validates and screens the request and returns { object: "dry_run", cost_usd, moderation } without generating or charging. A blocked prompt still returns the normal 422.
Your own id for the end user making this request (up to 128 characters, hashed at rest). Send it if your product serves many people: declined-prompt history, strikes and suspensions are then kept per end user, so one person's behaviour never affects another's requests or your account. After 10 severe violations that user gets 403 end_user_suspended; the id is echoed back as user in every screening error so you can act on it.
Response
202 · application/jsonTask
A task you poll with `GET /v1/videos/tasks/{id}`, the same shape as a video generation task.
Task id.
Always task.
Always video.
The model doing the edit.
queued at first.
What was debited now: the upper bound for the clip. Settled to the processed seconds when the task finishes.
/v1/videos/tasks/{id}, relative to the base URL.
Was this page helpful?