Documentation
API Reference
A unified REST API for streaming and downloading audio from YouTube and SoundCloud. All upstream CDN domains are fully proxied โ clients only ever see your domain.
Typical Flow
Search or look up
Use /api/youtube/search?q= to find a video, or go directly to /api/youtube/[id] or /api/soundcloud/[...url] if you already have the link.
Receive proxied URLs
The response includes streamURL, downloadURL, and progressURL (YouTube only). The upstream CDN domain is encoded into an opaque token โ never visible to the client.
Poll progress (YouTube only)
YouTube needs a short conversion step. Poll progressURL every ~1 s until done: true. SoundCloud streams are ready immediately.
Play or save
Set an <audio> or <video> src to streamURL for inline playback with seeking. Link to downloadURL to save the file โ the filename will match the track title.
// 1. Look up a YouTube video
const data = await fetch('/api/youtube/dQw4w9WgXcQ').then(r => r.json());
// 2. Poll progress until ready (YouTube only)
let prog = { done: false };
while (!prog.done) {
prog = await fetch(data.progressURL).then(r => r.json());
if (!prog.done) await new Promise(r => setTimeout(r, 1000));
}
// 3a. Play inline
audioElement.src = data.streamURL;
// 3b. Trigger file download
window.location.href = data.downloadURL;/api/youtube/search?q={query}Search YouTube for videos. Returns up to 10 results, each with an apiURL pointing directly to the video endpoint.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| q | query | string | yes | Search query |
Response
{
"query": "never gonna give you up",
"total": 10,
"results": [
{
"videoId": "dQw4w9WgXcQ",
"title": "Rick Astley โ Never Gonna Give You Up",
"thumbnail": "https://i.ytimg.com/vi/.../hqdefault.jpg",
"author": "Rick Astley",
"duration": "3:33",
"views": 1400000000,
"ago": "15 years ago",
"watchURL": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"apiURL": "https://yourdomain.com/api/youtube/dQw4w9WgXcQ"
}
]
}/api/youtube/[id]?format=mp3|mp4Fetch full metadata and proxied stream / download links for a YouTube video. Accepts a plain video ID or any YouTube URL format.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| id | path | string | yes | 11-char video ID or URL-encoded YouTube URL |
| format | query | mp3 | mp4 | no | Output format โ defaults to mp3 |
Response
{
"success": true,
"videoId": "dQw4w9WgXcQ",
"title": "Rick Astley โ Never Gonna Give You Up",
"author": "Rick Astley",
"description": "The official video...",
"thumbnails": {
"default": { "url": "...", "width": 120, "height": 90 },
"medium": { "url": "...", "width": 320, "height": 180 },
"high": { "url": "...", "width": 480, "height": 360 },
"standard": { "url": "...", "width": 640, "height": 480 },
"maxres": { "url": "...", "width": 1280, "height": 720 }
},
"streamURL": "https://yourdomain.com/api/stream/<token>",
"downloadURL": "https://yourdomain.com/api/download/<token>",
"progressURL": "https://yourdomain.com/api/progress/<token>"
}/api/soundcloud/[...url]Fetch full metadata and proxied links for a SoundCloud track. Accepts a plain path, a domain path, or a full URL โ all three forms work.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| url | path | string | yes | artist/track ยท soundcloud.com/artist/track ยท https://soundcloud.com/artist/track |
Response
{
"success": true,
"platform": "soundcloud",
"title": "Track Title",
"author": "Artist Name",
"description": "...",
"thumbnails": {
"small": "https://i1.sndcdn.com/artworks-...-large.jpg",
"medium": "https://i1.sndcdn.com/artworks-...-t300x300.jpg",
"large": "https://i1.sndcdn.com/artworks-...-t500x500.jpg",
"original": "https://i1.sndcdn.com/artworks-...-original.jpg"
},
"duration": "3:45",
"plays": 1200000,
"likes": 8400,
"genre": "Electronic",
"streamURL": "https://yourdomain.com/api/stream/<token>",
"downloadURL": "https://yourdomain.com/api/download/<token>"
}/api/stream/[token]Stream audio or video inline. Forwards Range headers so any browser player can seek. Always use the streamURL value from a video/track response โ never construct the token yourself.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| token | path | string | yes | Opaque base64url token from streamURL |
Response
Content-Type: audio/mpeg (or video/mp4) Content-Disposition: inline Accept-Ranges: bytes Content-Length: <file size>
/api/download/[token]Download the file with the correct filename. Supports full Unicode titles (Arabic, CJK, emojiโฆ) via RFC 5987.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| token | path | string | yes | Opaque base64url token from downloadURL |
Response
Content-Type: audio/mpeg (or video/mp4)
Content-Disposition: attachment; filename="Track Title.mp3";
filename*=UTF-8''Track%20Title.mp3/api/progress/[token]Poll the conversion progress for a YouTube request (not needed for SoundCloud). Poll every ~1 s until done is true.
Parameters
| Name | In | Type | Req | Description |
|---|---|---|---|---|
| token | path | string | yes | Opaque base64url token from progressURL |
Response
{
"progress": 2,
"stage": "converting video",
"done": false
}
// stage values (in order):
// "checking video" โ "extracting video" โ "converting video" โ "done"Try it live
Run a real request and inspect the raw JSON response.