Asset Delivery api:
Do not use this for licensed audio, doing so you’re breaking terms of use.
Instead use the toolbox service, example of the audio with id in your image: https://apis.roblox.com/toolbox-service/v1/items/details?assetIds=11717918968
Downloading licensed audio out of Roblox is against the Terms of Use, however if the audio isn’t licensed here is how to do it.
Send a post request to this endpoint: https://assetdelivery.roblox.com/v1/assets/batch
You have to include your cookie in it, so example headers for it would be e.g.:
"accept": "*/*",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "en-US,en;q=0.9",
"content-length": "49",
"content-type": "application/json",
"cookie": "YOUR COOKIE USE",
"origin": "https://music.roblox.com",
"priority": "u=1, i",
"referer": "https://music.roblox.com/",
"roblox-browser-asset-request": "true",
"roblox-place-id": "0",
"sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
"x-csrf-token": ""
And json payload would be e.g.:
[
{
"requestId": "123456789",
"assetId": 123456789
}
]
Doing this will output an audio file/blob url in the json response from Roblox
Do not use this for licensed audio, doing so you’re breaking terms of use.
yes thats the method, which is against the tos, and the secuirty is pretty weak, to get the audio you jsut send some header params and thats it.
i hypothetically did this and i got [{‘errors’: [{‘code’: 403, ‘message’: ‘User is not authorized to access Asset.’, ‘customErrorCode’: 1}], ‘requestId’: ‘9254155693’, ‘IsHashDynamic’: False, ‘IsCopyrightProtected’: False, ‘isArchived’: False, ‘assetTypeId’: 0}]
That’s odd, ill look into this endpoint more later and just update this reply. Maybe they enhanced this endpoint?
Update:
I’ve temporary made an endpoint which uses the asset delivery endpoint:
https://wokenews.net/roblox-audio
Simply do a get request by adding a query ?id=roblox_audio_id
.
Example response is:
{
"status": "success",
"audio_url": "https://cdn.wokenews.net/output_audio/audio.ogg"
}
It’s built on PHP, code:
<?php
header("Content-Type: application/json");
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["id"])) {
$audio_id = htmlspecialchars($_GET["id"]);
$cookie = "YOUR ROBLOX COOKIE";
$output_dir = "OUTPUT DIRECTORY";
$api_url = "https://assetdelivery.roblox.com/v1/assets/batch";
function generate_random_filename() {
return bin2hex(random_bytes(16));
}
function download_roblox_audio($audio_id, $cookie, $output_dir, $api_url) {
$payload = json_encode([
["requestId" => $audio_id, "assetId" => $audio_id]
]);
$headers = [
"accept: */*",
"accept-encoding: gzip, deflate, br, zstd",
"accept-language: en-US,en;q=0.9",
"content-length: " . strlen($payload),
"content-type: application/json",
"cookie: $cookie",
"origin: https://music.roblox.com",
"priority: u=1, i",
"referer: https://music.roblox.com/",
"roblox-browser-asset-request: true",
"roblox-place-id: 0",
'sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
"sec-ch-ua-mobile: ?0",
'sec-ch-ua-platform: "Windows"',
"sec-fetch-dest: empty",
"sec-fetch-mode: cors",
"sec-fetch-site: same-site",
"user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
"x-csrf-token: "
];
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_status !== 200) {
return ["error" => "Failed to fetch audio", "status" => $http_status];
}
$data = json_decode($response, true);
if (isset($data[0]["location"])) {
$audio_url = $data[0]["location"];
$random_filename = generate_random_filename() . ".ogg";
$audio_path = $output_dir . $random_filename;
if (!file_put_contents($audio_path, fopen($audio_url, 'r'))) {
return ["error" => "Failed to download audio"];
}
return ["audio_path" => $audio_path, "random_filename" => $random_filename];
}
return ["error" => "Invalid response"];
}
try {
$download = download_roblox_audio($audio_id, $cookie, $output_dir, $api_url);
if (isset($download["error"])) {
echo json_encode($download);
exit;
}
$cdn_url = str_replace($output_dir, "https://YOUR_DOMAIN/output_audio/", $download["audio_path"]);
echo json_encode(["status" => "success", "audio_url" => $cdn_url]);
} catch (Exception $e) {
echo json_encode(["error" => $e->getMessage()]);
}
} else {
echo json_encode(["error" => "Invalid request"]);
}
?>
For cookie part as I see it requires: GuestData=UserID=-, .RBXIDCHECK=, RBXImageCache=timg=, RBXSessionTracker=sessionid=, _t=, rbx-ip2=rbx-ip2, rbxas=, RBXEventTrackerV2=, UnifiedLoggerSession=, .ROBLOSECURITY=