Soundtrack a video
Score any video automatically. Submit a clip (uploaded file or YouTube URL), get a ranked list of Slipstream tracks that match the video's tone, pacing, and mood. Optionally render a final video with the track mixed in.
This isn't a single endpoint. It's an orchestration of four. The good news: each step is small, and you can stop after step 2 if all you need is the track list.
The flow
- Upload the video, either as a file or as a YouTube URL. You get back a
SoundtrackVideowith anidand asource_value. - Search for matching tracks by passing that
source_valueto the AI search endpoint. You get back a ranked list of tracks. - The user picks a track in your UI.
- Render and download a new video with the track mixed in. Only available for uploaded files, not YouTube URLs.
Step 1 — Upload the video
You have two options:
Upload a file (multipart form):
curl https://api.slipstreammusic.com/api/v4/soundtrack/video/ \
-X POST \
-H "Authorization: Bearer $PARTNER_API_KEY" \
-F "file=@/path/to/clip.mp4"Accepted formats: .mov, .mpeg, .mp4, .avi. Max 60 MB.
Or pass a YouTube URL (JSON):
curl https://api.slipstreammusic.com/api/v4/soundtrack/video/ \
-X POST \
-H "Authorization: Bearer $PARTNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'Response — 201 Created:
{
"id": "8a4b2c1d-9e7f-4a6b-b3c2-1f8d4e5a7c6b",
"source_type": "file",
"source_value": "5f3e7d9c8b2a4f1e6d0c5b8a3e2f7d9c",
"source_title": "clip.mp4",
"file": "https://media.slipstreammusic.com/.../clip.mp4"
}Hold on to two things: id (used in step 4) and source_value (used in step 2).
Uploaded files are stored temporarily and expire after a few days. If your user needs to revisit the result later, store the id and reference the same video in subsequent calls before it expires.
Step 2 — Search for matching tracks
Pass source_value to the AI search:
curl "https://api.slipstreammusic.com/api/v4/search/ai/by-video/?value=5f3e7d9c8b2a4f1e6d0c5b8a3e2f7d9c&limit=20" \
-H "Authorization: Bearer $PARTNER_API_KEY"The value parameter accepts both forms returned by step 1:
- An AIMS hash (32-char hex), when the user uploaded a file.
- A YouTube URL, when the user submitted a link.
You can narrow results with the same filter parameters used everywhere else in Search — genre, mood, bpm__range, etc.
Response — paginated list of Track objects, ranked by match score.
If you only need the track list, you can stop here. Show the results, let the user play previews, and you're done. The remaining steps are for delivering a finished video.
Step 3 — User picks a track
Render the results in your UI. Each Track has audio_url (a stream-proxy path) so users can preview without leaving your page.
When the user clicks a track to confirm, capture its id. That's what step 4 needs.
Step 4 — Render and download
Generate a single video with the chosen track mixed against the original audio. Only works for uploaded files — YouTube videos are licensed differently and can't be re-rendered.
curl https://api.slipstreammusic.com/api/v4/soundtrack/video/$VIDEO_ID/download/ \
-X POST \
-H "Authorization: Bearer $PARTNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"track_id": "1f3c4d5e-6a7b-8c9d-0e1f-2a3b4c5d6e7f",
"video_volume": 0.2,
"track_volume": 1.0,
"track_start": 0
}'| Field | Type | Description |
|---|---|---|
track_id | UUID | The picked track from step 3. |
video_volume | float, 0.0–1.0 | How much of the original video audio to keep. 0 mutes it. Default 1.0. |
track_volume | float, 0.0–1.0 | The new track's volume. Default 1.0. |
track_start | float, seconds | Where in the track to start playing. Useful for skipping intros. Default 0. |
The render is async. You'll get one of two responses:
200 OK — already cached, ready to download:
{ "url": "https://media.slipstreammusic.com/.../rendered.mp4" }202 Accepted — being processed, retry shortly:
{
"send_email": true,
"detail": "Download is being prepared. Please try again in a few moments."
}If send_email is true, the user will get an email with the download link once rendering finishes. Polling the same endpoint with the same parameters will return 200 with the URL once it's ready.
Error cases worth handling
| What | When | What to do |
|---|---|---|
| 422 Unprocessable Entity on upload | Video can't be analyzed (corrupt, too short, no audio) | Show the user error_code and detail from the body |
| 400 on download | Trying to render a YouTube-source video | Tell the user that downloads are only available for uploaded files |
| 404 on retrieve | Source file expired | Re-upload from the original |
| 401 on download | Caller isn't authenticated | The download endpoint requires a signed-in user |
Tips
- Step 2 is cacheable. The same
source_valuereturns the same ranked list. Cache it client-side per session so users can refine filters without re-running the AI. - Step 4 is idempotent for given parameters. Same video + same track + same volumes = same rendered URL. Reuse it.
- Stop at step 2 if your product just needs suggestions. Steps 3 and 4 are only for products that ship a finished video back.