sonilo-cli
Command-line interface for the Sonilo API — generate music and sound effects from text or video.
Install
pip install sonilo-cli
Auth
Set your API key once:
export SONILO_API_KEY=sk-...
or pass --api-key sk-... on any command.
Commands
sonilo account # plan limits and available services
sonilo usage --days 7 # usage summary
sonilo text-to-music --prompt "warm lo-fi piano, rain" --duration 30
sonilo video-to-music --video clip.mp4 --prompt "tense synths" --format wav
sonilo text-to-sfx --prompt "glass shattering on concrete" --duration 3
sonilo video-to-sfx --video clip.mp4 --output whoosh.wav
sonilo video-to-sfx --video clip.mp4 --segments @segments.json
sonilo video-to-sound --video clip.mp4 \
--music-prompt "uplifting orchestral score" --sfx-prompt "match the on-screen action"
sonilo video-to-video-music --video clip.mp4 --prompt "tense synths" --output scored.mp4
sonilo video-to-video-sfx --video clip.mp4 --segments @segments.json --output scored.mp4
sonilo video-to-video-sound --video clip.mp4 --music-prompt "tense synths"
sonilo dubbing --video-url https://example.com/clip.mp4 --languages es,fr --output dubbed.mp4
# writes dubbed.es.mp4 and dubbed.fr.mp4
sonilo tasks get <task-id>
sonilo tasks wait <task-id> --poll-interval 2 --timeout 600
Notes
text-to-music/video-to-musicstream a short.m4aby default.--format wav,--preserve-speech,--variantsabove 1, and the legacy alias--isolate-vocalseach switch to the async submit-and-poll path.text-to-sfx/video-to-sfxare always async;--formatacceptswav|mp3|aac|flac.- Output defaults to
./output.<ext>; override with--output.
Segments
--segments scores a timeline instead of one whole-clip prompt. It takes a JSON array, in one of
three forms — inline, from a file, or from stdin:
sonilo text-to-music --prompt "warm lo-fi piano" --duration 30 \
--segments '[{"start":0,"label":"intro","prompt":"airy pads"}]'
sonilo video-to-sfx --video clip.mp4 --segments @segments.json
jq -c '.cues' storyboard.json | sonilo video-to-sfx --video clip.mp4 --segments @-
A value starting with @ names a source to read the JSON from, and @- reads standard input — the
same convention as curl, gh and aws. Anything else is parsed as JSON directly.
The two segment shapes are not interchangeable:
| Shape | Commands | Fields |
|---|---|---|
| Music | text-to-music, video-to-music |
{start, prompt, label?} |
| SFX | video-to-sfx, video-to-video-sfx, video-to-sound, video-to-video-sound |
{start, end, prompt} |
start/endare seconds from the start of the track or clip.- Passing one shape to a command that takes the other is rejected before any request is made, with a message naming the shape that command expects.
- Only the shape is checked locally. Timing rules — the first segment starting at 0, minimum
spacing between segments, the
labelvocabulary, how many segments are allowed — are enforced by the API, which answers with a422describing what it rejected. - Keys the CLI does not recognise are forwarded as-is, so a newly added API field works without upgrading the CLI.
text-to-sfxtakes no segments (its output is a single effect, not a timeline).video-to-video-musictakes no segments either — the API scores the whole clip in one pass.
Variants
--variants N (1-10, default 1) generates that many distinct variants in one request instead of
one, on text-to-music, video-to-music, video-to-video-music, video-to-sound, and
video-to-video-sound. Cost scales linearly — --variants 3 costs three times a single-variant
request — and values above 1 are never covered by the free trial.
sonilo text-to-music --prompt "warm lo-fi piano" --duration 30 --variants 3 --output take.m4a
# writes take.0.m4a, take.1.m4a, take.2.m4a
--variantsabove 1 forces the async submit-and-poll path (see Notes above).- With
--variantsunset (or1), a command writes the single--outputfile exactly as before this flag existed. Above 1, it instead writes one file per variant, with the variant index spliced before the extension:take.m4abecomestake.0.m4a,take.1.m4a, etc. — the same naming--stemand dubbing's per-language output already use. - On
video-to-sound/video-to-video-sound,--stemis applied per variant too, e.g.take.0.music.m4a.
Scored video
video-to-video-music and video-to-video-sfx are the video-out counterparts of video-to-music
and video-to-sfx: same generation, but what comes back is the source picture with the new audio
already muxed in, so there is nothing to line up afterwards. Both are async-only and write a single
file (default output.mp4):
sonilo video-to-video-music --video clip.mp4 --prompt "tense synths" --output scored.mp4
sonilo video-to-video-sfx --video clip.mp4 \
--segments '[{"start":0,"end":5,"prompt":"footsteps on gravel"}]' --output scored.mp4
--promptis optional on both; without it the model scores from the picture alone.video-to-video-musicalso takes--preserve-speech, which keeps source speech in the mix; omitting it leaves the server default untouched.--isolate-vocalsis a legacy alias for the same flag — the API ORs the two together, and this endpoint returns one muxed video with no separate vocals stem.video-to-video-sfxtakes--segmentsin the SFX shape{start, end, prompt}— see Segments.- Neither command exposes
--format: the output is a video, not an audio file. - For music and effects in one call, use
video-to-video-soundbelow. video-to-video-musicalso takes--variants— see Variants above.video-to-video-sfxdoes not.
Combined soundtracks
video-to-sound and video-to-video-sound score a clip with a music bed and sound effects in one
call (one charge, instead of chaining two requests). Both are async-only and take the same options —
they differ only in what comes back: video-to-sound writes the mixed audio (default
output.wav), video-to-video-sound writes the source video with that audio muxed in (default
output.mp4).
sonilo video-to-sound --video clip.mp4 \
--music-prompt "uplifting orchestral score" \
--sfx-prompt "match the on-screen action" \
--output soundtrack.wav --stem music --stem sfx
--music-prompt/--sfx-promptsteer the two layers separately; both are optional.--segmentsplaces individual effects on the timeline, in the SFX shape{start, end, prompt}— see Segments.--preserve-speechkeeps speech from the source video in the mix.- Ducking is off by default. Pass
--duckingto bring the source video's own speech into the mix with the generated bed dipped under it — without it the result is the generated music and effects alone. Omitting both flags leaves the server default untouched;--no-duckingstill works and now just states that default explicitly. --stemis repeatable (music,music_processed,sfx) and saves the individual layers next to the combined output, so you can re-balance the mix yourself. With--output soundtrack.wav, the music stem lands atsoundtrack.music.m4a.music_processedexists only when--preserve-speechor ducking altered the music bed.- Both also take
--variants— see Variants above.
Dubbing
dubbing dubs a video into one or more target languages in a single async call:
sonilo dubbing --video-url https://example.com/clip.mp4 --languages es,fr --output dubbed.mp4
# writes dubbed.es.mp4 and dubbed.fr.mp4
--languagesis comma-separated; omit it to use the server defaultzh_cn,es,fr. Supported codes:en, zh_cn, ja, ko, pt, es, de, fr, it, ru.- Source videos may be at most 180 seconds long.
--outputis a filename template, not a single destination: a dubbing task returns one video per language, so--output clip.mp4writesclip.es.mp4,clip.fr.mp4, etc.- Billing is per language, and dubbing has no free trial runs — see Free trial below.
--timeoutdefaults to 7200 seconds, matching the backend's own ceiling for a dubbing job (far longer than other commands' default, since dubbing can run well past the usualtasks wait --timeout 600). If the wait still times out, the task keeps running server-side — resume watching it withsonilo tasks wait <task-id>.
Free trial
Accounts created through self-serve signup start with free runs on most endpoints — no card required:
| Free runs | Endpoints |
|---|---|
| 2 each | text-to-music, text-to-sfx, audio-ducking |
| 1 each | video-to-music, video-to-sfx, video-to-video-music, video-to-video-sfx, video-to-sound, video-to-video-sound |
| 0 | dubbing |
Dubbing bills video duration × number of languages, so a free run on it would be worth far more
than a free run on any other endpoint — it has no free allowance and bills from the first call.
The table above is the current default. sonilo account prints the live numbers: the account JSON
goes to stdout, and when the account has a free-trial allowance one summary line goes to stderr:
Free trial: text-to-music 1/2 left, video-to-music 0/1 left
Because the summary is on stderr, sonilo account | jq .trial still sees clean JSON.
Once an endpoint's free runs are used up, calls to it bill at the normal rate — or, if the account
has never been funded, fail with HTTP 402: ... (trial_exhausted) until a payment method is added.
That is the one 402 a retry can never fix.
Rate limits
Two separate limits return HTTP 429, and they want opposite handling. The CLI prints the API's
own sentence, so the wording says which one you hit:
sonilo: HTTP 429: Rate limit exceeded: your account allows 60 requests per minute. Please retry after 1 minute. To raise your limit, please contact info@sonilo.com. (rate_limit_exceeded)
sonilo: HTTP 429: Too many concurrent generations: 5 of 5 in progress. Please wait for one to finish before starting another. To raise your limit, please contact info@sonilo.com. (rate_limit_exceeded)
The first means calls are going out too fast. The counter runs on a fixed 60-second window and rejected calls count toward it too, so wait the window out instead of retrying inside it. The second means every generation slot is busy — waiting alone frees nothing, a running generation has to finish first.
sonilo account prints the account's own rpm_limit and concurrency_limit; the numbers above
are the standard-tier defaults. Email info@sonilo.com to raise either.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sonilo_cli-0.9.0.tar.gz.
File metadata
- Download URL: sonilo_cli-0.9.0.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaa4e1b5a0b44ed27fd569add00e5e480c770378317b4b981492cddca54c9ede
|
|
| MD5 |
01d7f283566abd40f733ac9dde373299
|
|
| BLAKE2b-256 |
f98de6cebb6ec7e278e0bb99abe901d35fa9e827e44cad9c7d3cfbe2cd93911c
|
Provenance
The following attestation bundles were made for sonilo_cli-0.9.0.tar.gz:
Publisher:
publish-cli.yml on sonilo-ai/sonilo-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sonilo_cli-0.9.0.tar.gz -
Subject digest:
eaa4e1b5a0b44ed27fd569add00e5e480c770378317b4b981492cddca54c9ede - Sigstore transparency entry: 2350534262
- Sigstore integration time:
-
Permalink:
sonilo-ai/sonilo-python@e450816dc2f6a4630a911c2c371446396dc42f9b -
Branch / Tag:
refs/tags/sonilo-cli-v0.9.0 - Owner: https://github.com/sonilo-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-cli.yml@e450816dc2f6a4630a911c2c371446396dc42f9b -
Trigger Event:
push
-
Statement type:
File details
Details for the file sonilo_cli-0.9.0-py3-none-any.whl.
File metadata
- Download URL: sonilo_cli-0.9.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0330ad7c25921fda4085bc94686b8cdd3e9cc16af6df9a4d7bf66f168cee49b9
|
|
| MD5 |
256725097e859be4152723e2f3bdc093
|
|
| BLAKE2b-256 |
f9e9711e64dad8da0a3da6c4267101bf7b5f4c826f9c73e6f31f5d1fff954343
|
Provenance
The following attestation bundles were made for sonilo_cli-0.9.0-py3-none-any.whl:
Publisher:
publish-cli.yml on sonilo-ai/sonilo-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sonilo_cli-0.9.0-py3-none-any.whl -
Subject digest:
0330ad7c25921fda4085bc94686b8cdd3e9cc16af6df9a4d7bf66f168cee49b9 - Sigstore transparency entry: 2350534618
- Sigstore integration time:
-
Permalink:
sonilo-ai/sonilo-python@e450816dc2f6a4630a911c2c371446396dc42f9b -
Branch / Tag:
refs/tags/sonilo-cli-v0.9.0 - Owner: https://github.com/sonilo-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-cli.yml@e450816dc2f6a4630a911c2c371446396dc42f9b -
Trigger Event:
push
-
Statement type: