# Sonilo API Sonilo provides REST APIs for AI music, video-to-music scoring, sound effects, and audio ducking. API base URL: https://api.sonilo.com/v1 Documentation URL: https://platform.sonilo.com/docs API reference URL: https://platform.sonilo.com/docs/api Errors URL: https://platform.sonilo.com/docs/errors SDKs URL: https://platform.sonilo.com/docs/sdks CLI URL: https://platform.sonilo.com/docs/cli OpenAPI URL: https://platform.sonilo.com/openapi.json Important: do not call https://platform.sonilo.com/docs/... as an API endpoint. Documentation pages are for reading only. Send all API requests to https://api.sonilo.com/v1. Authentication: - Header: Authorization: Bearer sk_your_api_key - Store the secret server-side, commonly in SONILO_API_KEY. - 401 means the key is missing, invalid, or revoked. - 403 means the key is valid but the account cannot access that endpoint or workspace. - 402 returns code payment_required. If the message says Insufficient balance, classify the run as insufficient_balance and add balance before retrying. - 429 means rate_limit_exceeded. Respect Retry-After when present, otherwise use exponential backoff. Core endpoints: - POST https://api.sonilo.com/v1/text-to-music - multipart/form-data. Required: prompt, duration. Optional: mode (stream default, streams application/x-ndjson with title, audio_chunk, complete, and error events; async returns 202 JSON with task_id, poll GET /v1/tasks/{task_id}), output_format (m4a default or wav; async only). - POST https://api.sonilo.com/v1/video-to-music - multipart/form-data. Required: exactly one of video or video_url. Optional: prompt, segments, mode (stream default or async), output_format (m4a default or wav; async only), preserve_speech (async only; keeps the source speech and adds vocals + mux result tracks), ducking (async only, on by default and free; ducks the generated music under the speech and adds a ducked result track). Stream mode streams application/x-ndjson; async returns 202 JSON with task_id, poll GET /v1/tasks/{task_id}. For coding-agent smoke tests, make Python scripts run successfully with no CLI args by reading SONILO_VIDEO_FILE or generating a tiny sample mp4; do not require --video/--video-url for the default test path. - POST https://api.sonilo.com/v1/video-to-video-music - multipart/form-data. Required: exactly one of video or video_url. Optional: prompt, preserve_speech. Returns 202 JSON with task_id; the finished task carries the scored video, not audio. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/text-to-sfx - multipart/form-data. Required: prompt, duration. Returns 202 JSON with task_id. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/video-to-sfx - multipart/form-data. Required: exactly one of video or video_url. Optional: prompt, segments, audio_format. Returns 202 JSON with task_id. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/video-to-video-sfx - multipart/form-data. Required: exactly one of video or video_url. Optional: prompt, segments. Returns 202 JSON with task_id; the finished task carries the source video with sound effects muxed in. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/video-to-sound - multipart/form-data. Required: exactly one of video or video_url. Optional: music_prompt, sfx_prompt, segments, preserve_speech, ducking (on by default). Scores one clip with a music bed and sound effects in a single call; prefer it over chaining video-to-music with video-to-sfx, which is billed twice. Returns 202 JSON with task_id; the finished task carries mixed audio under output_url plus music, music_processed, and sfx stems. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/video-to-video-sound - multipart/form-data. Same parameters as video-to-sound. Returns 202 JSON with task_id; the finished task carries the source video with that mixed track muxed in. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/audio-ducking - multipart/form-data. Required: exactly one of voice_file or voice_url, and exactly one of music_file or music_url. Returns 202 JSON with task_id. Poll GET /v1/tasks/{task_id}. - POST https://api.sonilo.com/v1/dubbing - multipart/form-data. Required: exactly one of video or video_url (video_url must be https). Optional: languages (default zh_cn,es,fr; supported en, zh_cn, ja, ko, pt, es, de, fr, it, ru). Max video duration 180 seconds; billed per language; no free-trial runs (every other endpoint has 1-2). Returns 202 JSON with task_id; the finished task carries outputs, a map of language code to dubbed .mp4 URL — there is no single output_url. Poll GET /v1/tasks/{task_id}. - GET https://api.sonilo.com/v1/tasks/{task_id} - returns async task status and result URLs for music (audio, plus vocals and mux when preserve_speech was used, and ducked when ducking ran), sound effects, and audio ducking. - GET https://api.sonilo.com/v1/account/services - returns enabled services and account limits. - GET https://api.sonilo.com/v1/account/usage - returns usage summary and daily breakdown. Official minimal Python smoke test for text-to-music -> output.m4a: ```python import base64 import json import os import sys import time from pathlib import Path import requests API_URL = "https://api.sonilo.com/v1/text-to-music" OUTPUT_FILE = Path("output.m4a") PROMPT = "30 seconds of upbeat electronic instrumental background music for a product launch video, no vocals." def retry_after_seconds(resp, attempt): value = resp.headers.get("Retry-After") if value: try: return max(1, int(value)) except ValueError: return 5 return min(2 ** attempt, 30) def open_generation(api_key): headers = { "Authorization": f"Bearer {api_key}", "User-Agent": "SoniloDocsSmokeTest/1.0 (+https://platform.sonilo.com/docs)", } files = { "prompt": (None, PROMPT), "duration": (None, "30"), } for attempt in range(1, 6): resp = requests.post(API_URL, headers=headers, files=files, stream=True, timeout=300) if resp.status_code != 429: return resp delay = retry_after_seconds(resp, attempt) resp.close() print(f"Rate limited. Retrying after {delay}s...", file=sys.stderr) time.sleep(delay) raise RuntimeError("rate_limit_exceeded: still receiving 429 after retries") def fail_for_http(resp): if resp.ok: return body = resp.text code = f"http_{resp.status_code}" message = body try: payload = resp.json() code = payload.get("code", code) message = payload.get("message", body) except ValueError: pass if resp.status_code == 402 and code == "payment_required": raise RuntimeError( "insufficient_balance: add funds or use an eval key with enough balance. " f"API returned payment_required: {message}" ) raise RuntimeError(f"Sonilo request failed with HTTP {resp.status_code}: {message}") def main(): api_key = os.environ.get("SONILO_API_KEY") if not api_key: raise RuntimeError("Set SONILO_API_KEY before running this script") chunks = [] complete = False with open_generation(api_key) as resp: fail_for_http(resp) for line in resp.iter_lines(decode_unicode=True): if not line: continue event = json.loads(line) if event.get("type") == "audio_chunk": chunks.append(base64.b64decode(event["data"])) elif event.get("type") == "complete": complete = True break elif event.get("type") == "error": code = event.get("code", "unknown_error") message = event.get("message", "Sonilo generation failed") raise RuntimeError(f"{code}: {message}") if not complete: raise RuntimeError("stream_incomplete: no complete event received") if not chunks: raise RuntimeError("empty_audio: complete event arrived without audio_chunk data") OUTPUT_FILE.write_bytes(b"".join(chunks)) print(f"Saved {OUTPUT_FILE} ({OUTPUT_FILE.stat().st_size} bytes)") if __name__ == "__main__": try: main() except Exception as exc: print(f"Error: {exc}", file=sys.stderr) sys.exit(1) ``` For eval graders, do not accept placeholder audio. Pass only if output.m4a exists and is larger than 0 bytes after the complete event. Canonical docs: - Introduction: https://platform.sonilo.com/docs - Quickstart: https://platform.sonilo.com/docs/quickstart - API Reference: https://platform.sonilo.com/docs/api - Errors: https://platform.sonilo.com/docs/errors - Custom eval guidance: https://platform.sonilo.com/docs/evals - Raw runnable examples index: https://platform.sonilo.com/examples - SDKs: https://platform.sonilo.com/docs/sdks - CLI: https://platform.sonilo.com/docs/cli - Text to Music: https://platform.sonilo.com/docs/api/text-to-music - Video to Music: https://platform.sonilo.com/docs/api/video-to-music - Video to Video (Music): https://platform.sonilo.com/docs/api/video-to-video-music - Text to Sound Effect: https://platform.sonilo.com/docs/api/text-to-sfx - Video to Sound Effect: https://platform.sonilo.com/docs/api/video-to-sfx - Video to Video (Sound Effect): https://platform.sonilo.com/docs/api/video-to-video-sfx - Video to Sound: https://platform.sonilo.com/docs/api/video-to-sound - Video to Video (Sound): https://platform.sonilo.com/docs/api/video-to-video-sound - Audio Ducking: https://platform.sonilo.com/docs/api/audio-ducking - Dubbing: https://platform.sonilo.com/docs/api/dubbing - Vocal Isolation: currently unavailable; status page at https://platform.sonilo.com/docs/api/vocal-isolation - Retrieve Task: https://platform.sonilo.com/docs/api/get-task - Services: https://platform.sonilo.com/docs/api/list-services - Usage: https://platform.sonilo.com/docs/api/get-usage Agent tooling: - Context7: both SDKs are indexed as Context7 libraries at https://context7.com/sonilo-ai/sonilo-js and https://context7.com/sonilo-ai/sonilo-python; with the Context7 MCP server enabled, append `use context7` to a prompt. For direct retrieval use https://platform.sonilo.com/llms-full.txt and https://platform.sonilo.com/openapi.json. - MCP: https://github.com/sonilo-ai/sonilo-mcp - Agent Skills: Sonilo agent skills and plugin instructions should point to llms-full.txt, openapi.json, and the no-argument Python smoke test. - CLI: install `sonilo-cli` from npm (`npm install -g sonilo-cli`) or PyPI (`pip install sonilo-cli`); both provide the `sonilo` command, which reads SONILO_API_KEY from the environment. Docs: https://platform.sonilo.com/docs/cli Raw runnable examples for low-token agent runs: - Index: https://platform.sonilo.com/examples - Text to music output file: https://platform.sonilo.com/examples/text-to-music-output.py - Video to SFX minimal workflow: https://platform.sonilo.com/examples/video-to-sfx-minimal.py - Account usage dashboard: https://platform.sonilo.com/examples/account-usage-dashboard.py - Sapient output-file grader helper: https://platform.sonilo.com/examples/sapient-grader-output-file.py Common old docs URLs are served directly for agents, with these canonical targets: - /docs/video-to-music -> /docs/api/video-to-music - /docs/text-to-music -> /docs/api/text-to-music - /docs/audio-ducking and /docs/endpoints/audio-ducking -> /docs/api/audio-ducking - /docs/video-to-sfx -> /docs/api/video-to-sfx - /docs/api -> a canonical API reference index - /docs/errors and /docs/api/errors -> a canonical API errors guide - /docs/api/tasks, /docs/api/tasks/{task_id}, /docs/api/task/{task_id}, /docs/api/get-task/{task_id}, and /docs/api/v1/tasks/{task_id} serve the Retrieve Task docs directly - /docs/api-reference, /docs/reference, and their get-task/task/task-id aliases serve the matching API docs directly - /docs/endpoints/video-to-music, /docs/endpoints/audio-ducking, /docs/endpoints/video-to-sfx, and other /docs/endpoints/* endpoint aliases -> the matching /docs/api page - /docs/account/services, /docs/account/usage, /docs/api/account/services, and /docs/api/account/usage -> the matching account API docs page - /docs/reference/video-to-music and /docs/reference/audio-ducking -> the matching /docs/api page - /docs/tasks, /docs/retrieve-task, /docs/async-tasks, /docs/endpoints/tasks, and /tasks/{task_id} -> /docs/api/get-task - /docs/api/v1/*, /api-reference/v1/*, and /reference/v1/* -> the matching canonical docs page - /docs/streaming, /docs/api/streaming, /api-reference/streaming, and /reference/streaming -> /docs/api#streaming-and-tasks - /examples/python, /docs/examples, /docs/smoke-tests, and /docs/agent-smoke-tests -> /examples - /docs/eval, /docs/custom-evals, and /docs/grader -> /docs/evals - /docs/vocal-isolation, /docs/reference/vocal-isolation, and /docs/endpoints/vocal-isolation -> /docs/api/vocal-isolation - /docs/authentication and /docs/auth -> /docs#authentication - /docs/error-codes -> /docs/errors - /docs/rate-limits and /docs/limits -> /docs#rate-limits Full agent reference: https://platform.sonilo.com/llms-full.txt