# Video to Music API

Canonical docs: https://platform.sonilo.com/docs/api/video-to-music
Source path: /fr/docs/api/video-to-music
Runtime API host: https://api.sonilo.com/v1

Do not send API requests to platform.sonilo.com, docs.sonilo.com, or local docs URLs. Documentation pages are for reading only. Send runtime requests to https://api.sonilo.com/v1 with Authorization: Bearer sk_your_api_key.

## Endpoint

POST /v1/video-to-music

## Summary

Generate a soundtrack that matches an uploaded video or video URL. Use this when timing, pacing, mood, duration, and scene changes should come from the video. Generated audio carries an inaudible provenance watermark.

## Use This For

- AI-generated music for video projects.
- Music for YouTube videos, ads, social videos, product demos, client videos, and video apps.
- Uploading a video and generating soundtrack options that match the video's mood, pacing, cuts, and duration.

## Related Guide

- [Generate music from a video file or URL with the REST API](https://sonilo.com/blog/guides/generate-music-from-video-file-url-rest-api): a walkthrough that sends a video file or a public video URL.

## Request

Content type: multipart/form-data

- `video` (file; optional): Max file size: default 300MB. Max duration: 6 minutes.
- `video_url` (string; optional): Max file size: default 300MB. Max duration: 6 minutes.
- `prompt` (string; optional): Optional text prompt to guide music generation, up to 2000 characters. For best results, omit this and let the model generate based on video content.
- `segments` (string; optional): Optional JSON array of timed segment prompts; the music changes style at each boundary. Each item has `start` (seconds; the first must be 0, starts strictly increasing and at least 5 seconds apart, the last at least 5 seconds before the end of the video), `prompt` (1-200 characters), and an optional `label` that must be exactly one of these values — any other value is rejected with a 422 error, and it defaults to `none` when omitted: `intro`, `verse`, `pre-chorus`, `chorus`, `bridge`, `break`, `silence`, `outro`, `none`. 1-30 items.
- `mode` (string; optional; default `stream`; one of `stream`, `async`): Optional. `stream` (default) returns this endpoint's streaming NDJSON response, unchanged. `async` returns 202 Accepted with a task_id instead of streaming; poll GET /v1/tasks/:task_id for the result.
- `output_format` (string; optional; default `m4a`; one of `m4a`, `wav`, `mp3`): `m4a` (default, AAC), `wav` (16-bit PCM) or `mp3` (320 kbps CBR). Applies to `audio`, to the `ducked` track when ducking ran, to the `mux` track when `preserve_speech` is used, and normally to every entry in `stems` (each stem's `content_type` reports what was actually delivered); the isolated `vocals` stem `preserve_speech` returns is unaffected. `wav` and `mp3` are transcoded server-side after generation and require mode=async — the streaming response is always m4a. The delivered MIME is echoed in `audio[].content_type`.
- `preserve_speech` (boolean; optional): Optional boolean, default `false`. When `true`, the original speech (dialogue, narration, or voice-over) is preserved while generating a new soundtrack. The model automatically isolates the speech from the source audio and composes music around it, preventing the original background music from influencing generation. Requires `mode=async` (the response has no room for the additional download links this adds — see GET /v1/tasks/:task_id's `vocals` and `mux` fields). No additional charge — billed the same as `preserve_speech=false`.
- `ducking` (boolean; optional; default `false`): Off by default. Set to true to also return a `ducked` audio track — the generated music dipped under the video's speech so dialogue stays intelligible — alongside the clean `audio`. Free of charge. Requires mode=async.
- `prompt_influence` (number; optional; default `0.5`; 0 to 1): How strongly the generated music follows the prompt: lower values let the video lead, higher values follow the prompt more literally. Omit to keep the default behavior. Free of charge.
- `variants_num` (integer; optional; default `1`; 1 to 10): How many distinct music variants to generate in one request. Each variant is a separate creative direction, returned as its own entry in the async result's `audio` array. Cost scales linearly — `variants_num=3` costs three times a single-variant request. Values above 1 require mode=async; the default of 1 is valid in stream mode. Values above 1 are never covered by the free trial and are always billed.
- `stems` (boolean; optional; default `false`): Off by default. Set to true to also return a `stems` array — the generated music split into four separated instrument tracks (`drums`, `bass`, `vocals`, `other`), each normally following the requested `output_format`, with `content_type` reporting what was actually delivered — alongside the clean `audio`. It splits the generated music, never the video's own audio. Free of charge. Requires mode=async. Separation runs after generation and typically adds 2-6 min to the wait and gives up after 30 min; that ceiling is reached by a retry or a busy queue rather than by track length, so do not size a client timeout off the duration. It never fails the task: if separation fails, `audio` is unaffected and the response carries `stems_error` — on its own, or alongside the streams that did separate.

Machine-readable schema: https://platform.sonilo.com/openapi.json

### Usage notes

- Provide exactly one of video or video_url.

## Response And Errors

- 200 stream returns application/x-ndjson with audio_chunk events and complete.
- 202 async mode returns task_id; poll GET /v1/tasks/{task_id}.
- 401 auth_invalid means the key is invalid or missing.
- 402 payment_required with insufficient_balance means generation cannot run until credits are available.
- 429 rate limited responses may include Retry-After.

## Example

```bash
curl -N -X POST "https://api.sonilo.com/v1/video-to-music" \
  -H "Authorization: Bearer sk_your_api_key" \
  -F "video=@/path/to/video.mp4" \
  -F "prompt=licensed soundtrack for a YouTube product video"
```

## Shared Error Handling

- 401 auth_invalid: set Authorization: Bearer sk_your_api_key on the request.
- 402 payment_required or insufficient_balance: add credits before rerunning; do not create fake audio.
- 403 forbidden: the key is valid but the account or service permission is missing.
- 404 not_found: check the endpoint path and host. Use https://api.sonilo.com/v1, not a docs URL.
- 429 rate_limit_exceeded: honor Retry-After and retry with backoff.

## Endpoint Vocabulary

- GET /v1/account/services
- GET /v1/account/usage
- POST /v1/text-to-music
- POST /v1/video-to-music
- POST /v1/video-to-video-music
- POST /v1/audio-ducking
- POST /v1/text-to-sfx
- POST /v1/video-to-sfx
- POST /v1/video-to-video-sfx
- POST /v1/video-to-sound
- POST /v1/video-to-video-sound
- GET /v1/tasks/{task_id}

