/download/{object_type}/{object_id}Download an audio or MIDI file by ID
Pass the file type and ID after processing finishes. The API redirects your server to a temporary signed URL. Follow the redirect and save or stream the returned file.
How this endpoint works
Use this endpoint when your app needs one completed result. Use the ZIP endpoint for multiple tracks or stems. This endpoint returns a 307 redirect with file bytes, not a JSON download object, so your HTTP client must follow redirects.
- 1
Wait for the file
Poll the matching job until is_complete is true.
- 2
Follow the redirect
Call the download API with an HTTP client configured to follow redirects.
- 3
Save or stream the file
Write the response bytes to disk, cloud storage, or directly to the user.
Common use cases
Choose this operation when it matches the source and result your workflow needs.
Download a song
Return the completed audio downloaded from a music link or uploaded by a user.
Download a restored WAV or master
Return one finished restoration or master as soon as its status reports completion.
Download a stem or MIDI file
Save one separated stem or MIDI transcription by its ID.
Processing used by 60,000+ music makers
Results people rely on
“I love the interface. I love the bulk upload/download features. They're a life saver! Also I just realized that Apollo is magic and I don't even need to use denoise. Apollo somehow removes noise much more naturally. So I'm actually spending way less credits than I expected.”
IMDK
“Love it! Makes everything crisp!”
The Grim Tower
“Sensacional”
Francisco
“Highend services!”
Tommi, Studionet
Code examples
Server-side example
import { writeFile } from "node:fs/promises";
const API_URL = "https://api.neuralanalog.com";
const API_KEY = process.env.NEURALANALOG_API_KEY;
async function waitForCompletion(objectType, objectId) {
while (true) {
const response = await fetch(`${API_URL}/status/${objectType}/${objectId}`, {
headers: { "X-API-Key": API_KEY },
});
if (!response.ok) {
throw new Error(`Status check failed with ${response.status}`);
}
const status = await response.json();
if (status.is_failed) {
throw new Error(status.error_message || `${objectType} processing failed`);
}
if (status.is_complete) {
return status;
}
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
const requestResponse = await fetch(`${API_URL}/upscale-audio`, {
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"audio_id": "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a",
"preset": "universal_enhancer",
"bit_depth": 24
}),
});
if (!requestResponse.ok) {
throw new Error(`Restoration request failed with ${requestResponse.status}`);
}
const result = await requestResponse.json();
const jobId = result["id"];
const status = await waitForCompletion("upscaled", jobId);
const downloadResponse = await fetch(
`${API_URL}/download/upscaled/${jobId}`,
{ headers: { "X-API-Key": API_KEY }, redirect: "follow" },
);
if (!downloadResponse.ok) {
throw new Error(`Download failed with ${downloadResponse.status}`);
}
await writeFile("restored.wav", Buffer.from(await downloadResponse.arrayBuffer()));Parameters
Send the API key from a trusted server. Never expose it in client-side JavaScript.
Path and query parameters
object_typeobject_idformattrackSuccessful response
Headers
LocationTemporary signed URL for the downloadable file.
Errors
X-API-Key returns an authentication error. Validation errors use the declared 422 response below.detailNo description provided.