# Edit Video

`POST /v1/videos/edits`

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`.

Base URL: `https://api.spicyapi.com`

## Authorizations

- `Authorization` (string, header, required): Bearer authentication header of the form `Bearer <token>`, where `<token>` is your SpicyAPI key (`sk-spicy-…`). Create one in the dashboard under API Keys.

## Body (application/json)

- `model` (string, required): `spicy-video-edit-1`, `spicy-cinema-1-edit` or `spicy-animate-1`.
- `video_url` (string, optional): 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.
- `prompt` (string, optional): 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`.
- `reference_image_urls` (string[], optional): 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`.
- `resolution` (string, optional): Instruction edits: `720P` (default) or `1080P`.
- `aspect_ratio` (string, optional): `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.
- `keep_audio` (boolean, optional): Instruction edits: `true` keeps the clip's original soundtrack.
- `negative_prompt` (string, optional): Instruction edits: what to avoid.
- `seed` (integer, optional): Instruction edits: reproducibility seed.
- `enhance_prompt` (boolean, optional): `spicy-video-edit-1` only: let the model expand the prompt before editing.
- `image_url` (string, optional): `spicy-animate-1` only, required: the person who performs the motion, one of your generated images.
- `motion` (string, optional): `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`.
- `quality` (string, optional): `spicy-animate-1` only: `standard` (default) or `pro`, priced separately.
- `dry_run` (boolean, optional): 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.
- `user` (string, optional): 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.

## Request

```bash
# 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"
  }'
```

## Response: 202 application/json

Task

A task you poll with `GET /v1/videos/tasks/{id}`, the same shape as a video generation task.

- `id` (string, required): Task id.
- `object` (string, required): Always `task`.
- `type` (string, required): Always `video`.
- `model` (string, required): The model doing the edit.
- `status` (string, required): `queued` at first.
- `cost_usd` (number, required): What was debited now: the upper bound for the clip. Settled to the processed seconds when the task finishes.
- `poll_url` (string, required): `/v1/videos/tasks/{id}`, relative to the base URL.

```json
{
  "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"
}
```
