# Neural Analog API Docs Import audio from a file or supported public music link, then restore, master, split stems, transcribe to MIDI, and download the results. Base URL: https://api.neuralanalog.com Authentication: send `X-API-Key: $NEURALANALOG_API_KEY` with every request. Recommended flow: - Use `POST /from-link` for a supported public music URL or `POST /from-file` for a local file. - Poll `GET /status/{object_type}/{object_id}` until `is_complete` is true. - Queue restoration, mastering, stem separation, or audio-to-MIDI transcription with the completed source ID. - Download completed artifacts with `GET /download/{object_type}/{object_id}`. ## Download audio from Suno, Udio, and other AI music sites POST /from-link Send a public song, playlist, or creator-page link. Your app or agent gets an audio ID, waits for the download, then saves the file or sends it to restoration, mastering, stem splitting, or MIDI conversion. Summary: Import Audio From a Public Music Link Use this when: Use this endpoint to build a music downloader, back up a public AI music library, or process songs from links without downloading and uploading them again on your server. It downloads existing public audio; it is not an official Suno or Udio music-generation API. API behavior: Import a public audio link into Neural Analog with the AI music downloader API. **Call this first when your source is a URL.** The API creates an `audio_id` immediately, then downloads and analyzes the track in the background. Supported sources include Udio, SUNO, TopMediaAI, Musicful, Mureka, FlowMusic / Producer AI, FreeMusic, MusicGeneratorAI, AI Song Maker, OpenMusic, AI Song Generator, Treblo, Tad AI, Spotify, YouTube, playlists, and creator pages. This endpoint is the Udio Downloader API, SUNO Downloader API, TopMediaAI Downloader API, Musicful Downloader API, Mureka Downloader API, FlowMusic / Producer AI Downloader API, Treblo Downloader API, Tad AI Downloader API, and Spotify Downloader API entry point. Use it to import supported public links before audio upscaling, audio mastering, stem splitting, archive download, or single artifact download. After this endpoint returns: ```text 1. Save `audio_id` from the response. 2. Poll `GET /status/audio/{audio_id}` until `is_complete` is true. 3. Use that `audio_id` with `/upscale-audio`, `/master-audio`, `/create-stems`, `/download-archive`, or `/download/audio/{audio_id}`. ``` If the link expands into multiple tracks, the response may also include a `batch_id`. In that case, each imported track gets its own `audio_id` in the user's library. Workflow: 1. Send a public music link: Send the URL of a supported song, playlist, or creator page with your API key. 2. Wait for the download: Save audio_id and poll the download status until it completes or fails. 3. Save or process the song: Download the completed song or send its audio ID to restoration, mastering, stem separation, or MIDI conversion. Common use cases: - Build an AI music downloader: Let users paste a public Suno, Udio, Mureka, or other supported song link and download the audio in your app. - Back up a playlist or creator page: Import multiple public tracks from a supported playlist or creator page and keep a local copy. - Process an AI-generated song: Download a song first, then restore its audio, master it, split it into stems, or convert it to MIDI. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - url (required, string): Public audio, video, playlist, or creator URL to import. Supported sources include Suno, Udio, FlowMusic / Producer.ai, TopMediaAI, Musicful, iLoveSong, MusicCreator, AIMusicGen, MakeBestMusic, EasyMusic, MusicAI, FreeMusic, MusicGeneratorAI, AI Song Maker, OpenMusic, AI Song Generator, Mureka, Treblo, Tad AI, Spotify, and online source links. Example: "https://www.youtube.com/watch?v=0Y46Mr5g75o". - audio_id (optional, string | null): Existing audio ID to retry or replace. Omit this field to create a new audio asset. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". Success responses: - 200: Successful Response - audio_id (required, string): ID of the imported audio asset. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - status (required, string): Import state returned immediately after the background job starts. Example: "processing". - message (required, string): Human-readable status message for the import request. Example: "Download started". - batch_id (optional, string | null): Batch import ID when the submitted link expands into multiple tracks, such as a playlist or creator page. Example: "1f6a3a16-7c63-4ad7-9f6b-4af8b8a5f2f5". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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}/from-link`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ "url": "https://suno.com/song/example" }), }); if (!requestResponse.ok) { throw new Error(`Import failed with ${requestResponse.status}`); } const result = await requestResponse.json(); const jobId = result["audio_id"]; const status = await waitForCompletion("audio", jobId); const downloadResponse = await fetch( `${API_URL}/download/audio/${jobId}`, { headers: { "X-API-Key": API_KEY }, redirect: "follow" }, ); if (!downloadResponse.ok) { throw new Error(`Download failed with ${downloadResponse.status}`); } await writeFile("original.wav", Buffer.from(await downloadResponse.arrayBuffer())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/from-link", headers=HEADERS, json={'url': 'https://suno.com/song/example'}, ) request_response.raise_for_status() result = request_response.json() job_id = result["audio_id"] status = wait_for_completion("audio", job_id) download_response = requests.get( f"{API_URL}/download/audio/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("original.wav", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/from-link" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://suno.com/song/example"}') job_id=$(printf '%s' "$request_json" | jq -er '.audio_id') poll_until_complete "audio" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/audio/$job_id" -o "original.wav" ``` Related API endpoint documentation: - Poll import status: https://neuralanalog.com/api-docs/status-object-type-object-id - Restore the imported audio: https://neuralanalog.com/api-docs/upscale-audio Product pages and guides: - View supported imports: https://neuralanalog.com/supported-imports ## Upload audio for restoration, mastering, stems, or MIDI POST /from-file Send an audio file with multipart form data. Your app or agent gets an audio ID, waits for the upload to finish, then chooses what to do with the track. Summary: Upload From File Use this when: Use this endpoint when a user already has an audio file on their device or in your storage. It gives file uploads the same restoration, mastering, stem-splitting, MIDI, and download options as link downloads. Let your HTTP client set the multipart boundary. API behavior: Upload an audio file directly via multipart form data. **Use this when you have an audio file to upload directly, without a URL.** The API creates an `audio_id` immediately and finalizes the file in the background. Authenticate API clients with `X-API-Key: $NEURALANALOG_API_KEY`. Multipart form body: ```text - audio: required encoded audio file. - file_source: optional source label; defaults to "from_file". ``` After this endpoint returns: ```text 1. Save `audio_id` from the response. 2. Poll `GET /status/audio/{audio_id}` until `is_complete` is true. 3. Use that `audio_id` with `/upscale-audio`, `/master-audio`, `/create-stems`, `/download-archive`, or `/download/audio/{audio_id}`. ``` Example usage: ```python import os import requests with open("./my-audio.mp3", "rb") as audio: response = requests.post( "https://api.neuralanalog.com/from-file", headers={"X-API-Key": os.environ["NEURALANALOG_API_KEY"]}, files={"audio": audio}, data={"file_source": "from_file"}, ) if response.status_code == 200: audio_id = response.json()["audio_id"] ``` Workflow: 1. Upload the audio file: Attach the file to the audio field and optionally add a file source label. 2. Wait for the upload: Save audio_id and poll the upload status until it completes or fails. 3. Choose what happens next: Restore, master, split, transcribe, archive, or download the uploaded audio. Common use cases: - Add audio upload to your app: Accept an audio file from a user and send it to the API without making it public first. - Process a local music library: Upload tracks from a desktop tool, internal service, or batch script for automatic processing. - Support links and files: Give users the same processing choices whether they paste a link or upload a file. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. Multipart form data: - audio (required, string): Encoded audio file to upload. - file_source (optional, string): Source identifier for the uploaded file. Used to categorize the file in the user's library. Default: "from_file". Success responses: - 200: Successful Response - audio_id (required, string): ID of the uploaded audio asset. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - status (required, string): Status of the uploaded audio asset. Returns 'in_progress' while the file is being finalized in the background. Example: "in_progress". - message (required, string): Human-readable status message for the upload request. Example: "File uploaded successfully". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript import { readFile, 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 form = new FormData(); form.append( "audio", new Blob([await readFile("./my-audio.mp3")], { type: "audio/mpeg" }), "my-audio.mp3", ); form.append("file_source", "from_file"); const requestResponse = await fetch(`${API_URL}/from-file`, { method: "POST", headers: { "X-API-Key": API_KEY }, body: form, }); if (!requestResponse.ok) { throw new Error(`Upload failed with ${requestResponse.status}`); } const result = await requestResponse.json(); const jobId = result["audio_id"]; const status = await waitForCompletion("audio", jobId); const downloadResponse = await fetch( `${API_URL}/download/audio/${jobId}`, { headers: { "X-API-Key": API_KEY }, redirect: "follow" }, ); if (!downloadResponse.ok) { throw new Error(`Download failed with ${downloadResponse.status}`); } await writeFile("original.wav", Buffer.from(await downloadResponse.arrayBuffer())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) with open("./my-audio.mp3", "rb") as audio: request_response = requests.post( f"{API_URL}/from-file", headers=HEADERS, files={"audio": ("my-audio.mp3", audio, "audio/mpeg")}, data={"file_source": "from_file"}, ) request_response.raise_for_status() result = request_response.json() job_id = result["audio_id"] status = wait_for_completion("audio", job_id) download_response = requests.get( f"{API_URL}/download/audio/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("original.wav", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/from-file" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -F "audio=@./my-audio.mp3" \ -F "file_source=from_file") job_id=$(printf '%s' "$request_json" | jq -er '.audio_id') poll_until_complete "audio" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/audio/$job_id" -o "original.wav" ``` Related API endpoint documentation: - Poll upload status: https://neuralanalog.com/api-docs/status-object-type-object-id - Restore: https://neuralanalog.com/api-docs/upscale-audio - Split the uploaded audio: https://neuralanalog.com/api-docs/create-stems Product pages and guides: - Review supported audio sources: https://neuralanalog.com/supported-imports ## Check when an audio job is finished GET /status/{object_type}/{object_id} Audio processing takes time. Use one reusable polling loop to check downloads, restorations, masters, stem splits, and MIDI conversions. Your app or agent can continue as soon as the job finishes. Summary: Get Processing Status Use this when: Use this endpoint after any API call that starts background work. The same response fields work across job types, so your backend can handle completion, failure, and download URLs without writing a different status client for every feature. API behavior: Check whether a Neural Analog job or artifact is ready. **Use this after any endpoint that returns an ID for background work.** Importing, restoration, mastering, and stem separation all return before the heavy processing has finished. Poll this endpoint with the returned ID until `is_complete` is `true` or `is_failed` is `true`. Typical polling sequence: ```text POST /from-link -> audio_id GET /status/audio/{audio_id} POST /upscale-audio -> id GET /status/upscaled/{id} POST /master-audio -> id GET /status/mastered/{id} POST /create-stems -> creation_id GET /status/stem_split/{creation_id} POST /transcribe -> id GET /status/transcription/{id} POST /run-workflow -> workflow_run_id GET /status/workflow/{workflow_run_id} ``` When a downloadable artifact is complete, the response includes a `download_url`. You can also call `GET /download/{object_type}/{object_id}` directly with the same object type and ID. Workflow: 1. Save the job ID: Keep the ID and object type returned by the endpoint that started the job. 2. Check every few seconds: Poll the status API until is_complete or is_failed becomes true. 3. Continue or show the error: Download the finished result on success, or show error_message when processing fails. Common use cases: - Show processing status: Display processing, completed, and failed states in your app. - Chain API jobs: Wait for restoration to finish before starting mastering, stems, MIDI, or download. - Handle failures safely: Stop polling and return a useful error instead of leaving a worker running forever. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. Path/query parameters: - object_type (required, path, string): Object type to inspect: audio, upscaled, mastered, stem_split, stem, transcription, or workflow. - object_id (required, path, string): ID returned by a queueing endpoint. Success responses: - 200: Successful Response - object_type (required, string): Kind of object that was checked. Example: "upscaled". - object_id (required, string): ID of the checked job or artifact. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - status (required, string): Current processing state. Example: "completed". - is_complete (required, boolean): True when the artifact is ready to download or use. Example: true. - is_failed (required, boolean): True when the job cannot complete and error_message is set. Example: false. - download_url (optional, string | null): Download endpoint URL for completed downloadable artifacts. Example: "https://api.neuralanalog.com/download/upscaled/d66cf940-bf26-45bb-80f7-332f26b6859a". - audio_id (optional, string | null): Parent audio asset ID when the checked object belongs to a track. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - status_details (optional, string | null): Additional human-readable progress details when available. Example: "Restoration completed". - error_message (optional, string | null): Failure reason when is_failed is true. Example: "Source audio is no longer available". - created_at (optional, string | null): ISO timestamp for when the job or artifact was created. Example: "2026-05-05T10:15:30Z". - completed_at (optional, string | null): ISO timestamp for when processing completed. Example: "2026-05-05T10:18:42Z". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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); console.log(status); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/upscale-audio", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'preset': 'universal_enhancer', 'bit_depth': 24}, ) request_response.raise_for_status() result = request_response.json() job_id = result["id"] status = wait_for_completion("upscaled", job_id) print(status) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/upscale-audio" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","preset":"universal_enhancer","bit_depth":24}') job_id=$(printf '%s' "$request_json" | jq -er '.id') poll_until_complete "upscaled" "$job_id" printf '%s' "$status_json" | jq ``` Related API endpoint documentation: - Download the finished file: https://neuralanalog.com/api-docs/download-object-type-object-id - Package completed versions: https://neuralanalog.com/api-docs/download-archive - Review the complete API flow: https://neuralanalog.com/api-docs ## Restore low-quality audio and export a cleaner WAV POST /upscale-audio Send a compressed song, damaged recording, voice track, or stem. Choose what needs fixing. Your app or agent gets a restored WAV that is ready for editing, mastering, or download. Summary: Audio Upscaling API Use this when: Use this API when users need to upscale MP3 to WAV, restore missing high frequencies, fix compressed AI music, clean speech, remove clipping, reduce reverb, or repair a stem. Unlike file conversion, restoration predicts missing audio content. Choose Apollo, AudioSR, UniverSR, or a problem-specific preset after you know what the source needs. API behavior: Queue audio upscaling and restoration for a track, stem, or previous restoration. **Use this after the source audio is complete.** If you imported from a link, first poll `GET /status/audio/{audio_id}` until `is_complete` is true. Then pass that `audio_id` here. You may also pass `stem_id` to restore one stem, or `source_upscaled_id` to run another restoration pass on an existing restored version. The Audio Upscaling API runs GPU-powered enhancement on imported files, stems, mastered artifacts, or previous restorations so the result can be downloaded, mastered, or used for stem splitting. The endpoint returns immediately with `id`, the restored artifact ID: ```text POST /upscale-audio -> id GET /status/upscaled/{id} GET /download/upscaled/{id} ``` Choose `preset`, `model_name`, `stereo_mode`, and related restoration fields to control the repair style. The user's plan must allow the selected preset. Workflow: 1. Choose the audio and problem: Send the track or stem ID and choose the restoration preset that matches the damage. 2. Wait for restoration: Save id and poll the restoration job until it finishes or fails. 3. Download the restored WAV: Download the cleaner file or send it directly to mastering or stem separation. Common use cases: - Upscale MP3 to WAV: Rebuild missing high frequencies and reduce MP3 compression artifacts before editing or mastering. - Fix hiss, clipping, or reverb: Choose a problem-specific preset for a noisy AI song, clipped recording, reverberant vocal, or damaged stem. - Restore voice recordings: Improve low-bandwidth speech, vocals, podcasts, phone calls, or voice notes before publishing. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - audio_id (required, string): Identifies the full audio file to restore. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - preset (optional, string): Selects the restoration model or repair process to run. Each preset supports its own parameters; fields that do not apply to the selected preset are ignored. Allowed: "universal_enhancer", "constant_bpm", "novasr", "flashsr", "dacvae", "declip", "dialogue_isolate", "denoise", "dereverb", "decrowd", "phantom_center", "audiosr", "apollo_voice", "lavasr", "reuse", "acestep_15_xl", "stable_audio_3", "universr", "aero". Default: "universal_enhancer". - stereo_mode (optional, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. Allowed: "single_pass", "mid_sides", "left_right", "mono". Default: "single_pass". - frequency_cutoff (optional, integer): Sets the upper frequency boundary in hertz where a bandwidth-extension model starts rebuilding audio. Supported by audiosr and universr. AudioSR accepts 3000, 4000, 5000, 8000, 10000, 13000, or 16000. UniverSR accepts 4000, 6000, 8000, or 12000. Other presets ignore this field. Default: 13000. - model_name (optional, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. Allowed: "denoise", "denoise_debleed", "music_musedb", "voice_4_16", "voice_8_16", "voice_8_24", "voice_12_48", "universr-audio", "universr-audio-finetune-v1", "universr-vocal", "acestep-v15-xl-turbo", "acestep-v15-xl-sft", "stable-audio-3-medium". Default: "music_musedb". - reconstruction_method (optional, string): Controls how generated high frequencies are combined with the source audio. Supported by audiosr and universr. For AudioSR, multiband_ensemble low-passes the original audio at frequency_cutoff minus 1000 Hz, high-passes the AudioSR output at the same crossover, then sums both bands. original_signal uses frequency_cutoff as a hard final spectrum boundary: original source bins below the cutoff and generated bins at or above it. For UniverSR, original preserves the legacy reconstruction path, while original_signal keeps the bandwidth-limited input for model conditioning but takes the final low-frequency bins from the original 48 kHz source signal. Other presets ignore this field. Allowed: "multiband_ensemble", "original", "original_signal". Default: "original". - strength (optional, number): Controls processing intensity from subtle cleanup to aggressive restoration. Higher values preserve less of the degraded source. Supported by acestep_15_xl and stable_audio_3. Other presets ignore this field. Default: 0.95. - prompt (optional, string): Describes the sound that a prompt-guided model should create from the source audio. Supported by acestep_15_xl and stable_audio_3. Other presets ignore this field. Keep the prompt under 256 characters. Default: "high quality remaster, studio recording, official release, CD quality.". Example: "clean studio master, full bandwidth, natural transients". - prompt_strength (optional, number): Controls how strongly Stable Audio 3 follows prompt relative to the reference audio. Higher values give the prompt more influence. Supported by stable_audio_3 only; other presets ignore this field. Accepts values from 0 to 10. Default: 1. - inpaint_regions (optional, array | null): Lists source time ranges to regenerate while preserving the rest of the input audio. Each range requires start and end times in seconds. Supported by stable_audio_3 only; other presets ignore this field. Omit it to run an ordinary audio-to-audio remix. Example: [{"end":8,"start":4}]. - stem_id (optional, string | null): Selects one stem from the parent audio as the restoration source. Omit it to restore the full audio file. Example: "abf8a992-1c4e-4935-93f0-197116e77e49". - source_upscaled_id (optional, string | null): Selects an existing restored version as the source for another pass. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - source_mastered_id (optional, string | null): Selects an existing mastered artifact as the restoration source. Example: "f5db8e4b-2e74-4198-a8de-0c3a398620e9". - source_temporary_mix_key (optional, string | null): Short-lived Current Main Mix or Current All Stems Mix R2 source key. - selection (optional, object | null): Limits restoration to a start and end time in seconds. Omit it to restore the full selected source. Example: {"end":42,"start":12.5}. - bit_depth (optional, integer): Output WAV bit depth for the restored audio. Allowed: 16, 24. Default: 24. - hq_streaming_format (optional, string): Selects the compressed format generated for browser playback and streaming alongside the restored WAV output. Allowed: "aac", "mp3", "flac". Default: "aac". Model and parameter reference: ### Choose what you want to fix Selector field: `preset`. Models and API values: - `preset="universal_enhancer"` (MP3 Music Restoration (Apollo, 2025)): Upscale low quality MP3 back to high quality. Trained on pairs of high quality music, and their degraded mp3 versions. Restores missing high frequencies and removes compression artifacts. Output sample rate matches the prepared input rate (44.1kHz or 48kHz). Recommended for: online source imports, songs downloaded from the internet, compressed sound, tracks missing >16Khz. Not effective to regenerate 16Khz+ audio? Try AudioSR instead. - Parameters: - `stereo_mode` (Stereo Mode, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `mid_sides` (Stereo (Mid/Sides)), `left_right` (Stereo (L/R)). - `preset="stable_audio_3"` (Neural Remix - Stable Audio 3 (Stable Audio 3 Medium, 2026)): Recreates the track with Stability AI's Stable Audio 3 Medium audio-to-audio editing model. This prompt-guided remix mode uses the source audio as a reference while the text prompt steers style, tone, and instrumentation. Recommended for: creative remixes, inpainting missing musical ideas, alternate takes, and low-end or texture repair that benefits from generative reconstruction. Try a short section first for predictable results. - Parameters: - `strength` (Remix Strength, number): How much Stable Audio 3 can reinterpret the source. Higher values let the model rewrite more of the original recording. - Common values: `0.01` (Minimal edit), `0.1` (Light edit), `0.3` (Bit more edit), `0.5` (Balanced edit) **Recommended**, `0.6` (Moderate remix), `0.75` (Strong remix), `0.95` (Totally different song) **Default**. - `prompt` (Prompt, string): Describe the target sound, style, instrumentation, tempo, and production character Stable Audio 3 should create from the source audio. - Default: "high quality remaster, studio recording, official release, CD quality.". - Example: "clean studio master, full bandwidth, natural transients". - `prompt_strength` (Prompt Strength, number): How strongly Stable Audio 3 follows the text prompt. Higher values amplify prompt guidance relative to the reference audio. - Range: 0 to 10. - Common values: `0.5` (Less prompt strength), `1` (Base prompt strength) **Default** **Recommended**, `2` (More prompt), `4` (Even more prompt), `7` (Maximum prompt). - `0.5`: Keeps the prompt influence light so the source audio remains the main guide. - `1`: Uses the normal Stable Audio 3 prompt conditioning strength. - `2`: Makes the prompt easier for the model to follow while still leaving room for the reference audio. - `4`: Pushes the result harder toward the described style, instruments, or production character. - `7`: Strongly prioritizes the prompt and can make the result less faithful to the reference audio. - `model_name` (Model variant, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. - Allowed values: `stable-audio-3-medium` (Stable Audio 3 Medium) **Recommended**. - `inpaint_regions` (Inpaint regions, Array<{ start: number; end: number }> | null): Lists source time ranges to regenerate while preserving the rest of the input audio. Each range requires start and end times in seconds. Supported by stable_audio_3 only; other presets ignore this field. Omit it to run an ordinary audio-to-audio remix. - Example: [{"end":8,"start":4}]. - `preset="acestep_15_xl"` (Neural Remix - ACEStep 1.5 XL (ACE-Step 1.5 XL, 2026)): Recreates the track with the ACE-Step XL 2026 music generation model in remix mode. This is similar to SUNO 'cover' mode. It will use similar sounds as the reference, but use new notes if you lower the reference strength. Recommended for: Bass tracks, inpainting missing notes in stems, low end mudiness. Interesting results when blended with the original audio. - Parameters: - `model_name` (Model, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. - Allowed values: `acestep-v15-xl-turbo` (AceSTEP turbo), `acestep-v15-xl-sft` (AceSTEP SFT). - `strength` (Original Influence, number): How much the original audio influences the result. 1.0 means the model tries to match the original as close as possible. 0.1 means it's a loose reference. - Common values: `1.0` (As close as possible), `0.99` (Almost original), `0.5` (Inspiration), `0.1` (Creative interpretation). - `prompt` (Prompt, string): AceSTEP XL is a 2026 music generation model similar to SUNO. This prompt is passed to the model to influence the result. ACE Step authors mention that it's best if it describes the original track: style, instruments, tempo, key. - Default: "high quality remaster, studio recording, official release, CD quality.". - Example: "clean studio master, full bandwidth, natural transients". - `preset="audiosr"` (AudioSR Upscaler (Audio SR, 2022)): Regenerates high frequencies above the selected cutoff while keeping lower frequencies from the original audio. Recommended for: Low quality recordings, missing high frequencies, hissing noise around 10Khz (hihats, voice, suno hiss). Low thresholds (eg: 3Khz) will change audio the most, while high threshold will mostly preserve what's already here. Not recommended for: Bass tracks, muddy low end. Use Neural Remix instead. - Parameters: - `frequency_cutoff` (Strength, integer): Sets where AudioSR starts regenerating high frequencies. Lower cutoffs regenerate more of the track for a stronger effect; higher cutoffs focus on the top end for a subtler, more nuanced result. - Allowed values: `16000` (Very Subtle (16 kHz cutoff)), `13000` (Subtle (13 kHz cutoff)) **Default**, `10000` (Mild (10 kHz cutoff)), `8000` (Medium (8 kHz cutoff)) **Recommended**, `5000` (Pronounced (5 kHz cutoff)), `4000` (Strong (4 kHz cutoff)), `3000` (Very Strong (3 kHz cutoff)). - `reconstruction_method` (Reconstruction, string): Controls how generated high frequencies are combined with the source audio. Supported by audiosr and universr. For AudioSR, multiband_ensemble low-passes the original audio at frequency_cutoff minus 1000 Hz, high-passes the AudioSR output at the same crossover, then sums both bands. original_signal uses frequency_cutoff as a hard final spectrum boundary: original source bins below the cutoff and generated bins at or above it. For UniverSR, original preserves the legacy reconstruction path, while original_signal keeps the bandwidth-limited input for model conditioning but takes the final low-frequency bins from the original 48 kHz source signal. Other presets ignore this field. - Allowed values: `multiband_ensemble` (Multiband Ensemble) **Recommended**, `original_signal` (Seamless Reconstruction). - `multiband_ensemble`: Low-passes the original audio at cutoff minus 1Khz, high-passes the AudioSR output at the same crossover, then sums both bands. Falls back to raw AudioSR if the source already cuts off below 14Khz. - `original_signal`: Feeds AudioSR a low-passed copy by downsampling to 2x the cutoff minus 1Khz, then keeps the original source below the selected cutoff and uses the generated signal above it. - `stereo_mode` (Channels, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `single_pass` (Mono) **Default**, `mid_sides` (Stereo (Mid/Sides)) **Recommended**. - `preset="universr"` (UniverSR Upscaler (UniverSR, 2026)): Upscale music, voice, and sound effects. UniverSR is a 2026 model developed by the University of Seoul which performs audio super-resolution directly in the complex STFT domain using flow matching. Very similar to AudioSR, but with more coherent high ends. Recommended for: Low quality recordings, missing high frequencies, hissing noise around 10Khz (hihats, voice, suno hiss). Low thresholds (eg: 4Khz) will change audio the most, while high threshold will preserve what's already here. Not recommended for: muddy bass or muddy low end. Use Neural Remix instead. - Parameters: - `model_name` (Model, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. - Allowed values: `universr-audio` (Original) **Recommended**, `universr-audio-finetune-v1` (Fine-tune v1). - `frequency_cutoff` (Strength, integer): Sets the upper frequency boundary in hertz where a bandwidth-extension model starts rebuilding audio. Supported by audiosr and universr. AudioSR accepts 3000, 4000, 5000, 8000, 10000, 13000, or 16000. UniverSR accepts 4000, 6000, 8000, or 12000. Other presets ignore this field. - Allowed values: `12000` (Subtle (12 kHz cutoff)), `8000` (Medium (8 kHz cutoff)) **Recommended**, `6000` (Pronounced (6 kHz cutoff)), `4000` (Strong (4 kHz cutoff)). - `stereo_mode` (Channels, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `mid_sides` (Stereo (Mid/Sides)), `left_right` (Stereo (L/R)), `single_pass` (Mono) **Default**. - `reconstruction_method` (Reconstruction, string): Controls how generated high frequencies are combined with the source audio. Supported by audiosr and universr. For AudioSR, multiband_ensemble low-passes the original audio at frequency_cutoff minus 1000 Hz, high-passes the AudioSR output at the same crossover, then sums both bands. original_signal uses frequency_cutoff as a hard final spectrum boundary: original source bins below the cutoff and generated bins at or above it. For UniverSR, original preserves the legacy reconstruction path, while original_signal keeps the bandwidth-limited input for model conditioning but takes the final low-frequency bins from the original 48 kHz source signal. Other presets ignore this field. - Allowed values: `original_signal` (Seamless Reconstruction), `original` (Original Reconstruction) **Default** **Recommended**. - `original_signal`: Keeps the original 48 kHz low-frequency bins in the final spectrum while still using the cutoff signal for model conditioning. This usually avoids a visible crossover seam because the low band keeps the source frequency profile. - `original`: Legacy UniverSR assembly. The final low band comes from the downsampled and upsampled cutoff signal, whose resampling rolloff can dip energy near the cutoff and leave a seam where generated highs begin. - `preset="novasr"` (NovaSR Speech Upscaler (NovaSR, 2026)): Upscaling model trained on English speech. Best for restoring podcasts, voice-overs, or isolated vocal tracks. - Parameters: - `stereo_mode` (Channels, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `single_pass` (Mono) **Default**, `mid_sides` (Stereo (Mid/Sides)). - `preset="flashsr"` (FlashSR Upscaler (FlashSR, Jan 2025)): Fast single-step super-resolution model for bandwidth extension and detail recovery. Recommended for: Western music, single instrument upscaling, preparing 44.1Khz stems before Atmos Export. Not recommended for: Bass. - Parameters: - `stereo_mode` (Stereo Mode, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `mid_sides` (Stereo (Mid/Sides)), `left_right` (Stereo (L/R)), `single_pass` (Mono) **Default**. - `preset="constant_bpm"` (Remove speed variation (make bpm constant) (Beat This!, 2024)): Fixes wonky tempo in music generated by SUNO when the speed keeps changing throughout the song. Recommended for: SUNO songs that should stay at a constant BPM and align cleanly to a beat grid. It can also help tighten tempo variations in live performances. - Parameters: none. - `preset="dacvae"` (Neural Reconstruction (DACVAE, 2024)): Leverage the DACVAE neural codec to regenerate all frequencies. Helps with removing out of distribution frequencies. Recommended for: weird hihats sounds in electronic music. - Parameters: - `stereo_mode` (Channels, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `single_pass` (Mono) **Default**, `mid_sides` (Stereo (Mid/Sides)). - `preset="declip"` (Remove Clipping): Fixes harsh crackling when volume is too high. Algorithms find optimal settings to remove all crackling, while still maintaining loudness. - Parameters: none. - `preset="dialogue_isolate"` (Remove Room Echo): Remove short reverb from voice recordings recorded a room with a laptop microphone. Good for podcasts, voice-overs, and dialogue that have a subtle room echo. Less effective on music or singing. - Parameters: none. - `preset="denoise"` (Remove Noise): Reduces hiss, hum, background noise, and optional source bleed while keeping the main vocals/instruments. Uses the same model family as stem splitting, but returns a single cleaned track only. - Parameters: - `model_name` (Model Variant, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. - Allowed values: `denoise` (Denoise) **Recommended**, `denoise_debleed` (Denoise and debleed). - `preset="dereverb"` (Remove Long Reverb): Removes long reverb tails, delay, and echo to make the sound drier. Great for singing, music, and live recording with hall echo. Not too good with subtle echo in clean recording. Uses the same model family as stem splitting, but returns a single dry track only. - Parameters: none. - `preset="decrowd"` (Remove Crowd Noise): Removes audience noise from live recordings while preserving the performance. Uses the same model family as stem splitting, but returns a single cleaned track only. - Parameters: none. - `preset="phantom_center"` (Keep Only Center Mono): Extracts the "phantom center", the content that should be mono in a track. Use this for: bass, kick drums, podcast voice. Removes phaser, chorus, or flanger from instrument stems. Good for mixing. - Parameters: none. - `preset="reuse"` (RE-USE Speech Enhancer (NVIDIA RE-USE, 2026)): Improve clarity, upscale, remove reverb, remove noise and audio glitches in multilingual speech. Recommended for: getting dry vocals, clearer podcasts, noisy voice notes, etc. Not recommended for: full music mixes or instrumental upscaling. Use UniverSR, AudioSR, or a music restoration model instead. - Parameters: - `stereo_mode` (Channels, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `single_pass` (Mono) **Default**, `mid_sides` (Stereo (Mid/Sides)), `left_right` (Stereo (L/R)). - `preset="apollo_voice"` (Singing Upscaler (Apollo Voice, 2025)): Specialized voice upscaling. Restores missing high frequencies and removes compression artifacts in lower frequencies. Output sample rate is 44.1kHz for lower-rate inputs and 48kHz for 48kHz+ inputs. - Parameters: - `stereo_mode` (Stereo Mode, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. - Allowed values: `mid_sides` (Stereo (Mid/Sides)), `left_right` (Stereo (L/R)). Success responses: - 200: Successful Response - id (required, string): ID of the queued restored audio version. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - status (required, string): Queueing status for the restoration job. Example: "processing". - message (required, string): Human-readable queueing result. Example: "Audio restoration queued". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/upscale-audio", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'preset': 'universal_enhancer', 'bit_depth': 24}, ) request_response.raise_for_status() result = request_response.json() job_id = result["id"] status = wait_for_completion("upscaled", job_id) download_response = requests.get( f"{API_URL}/download/upscaled/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("restored.wav", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/upscale-audio" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","preset":"universal_enhancer","bit_depth":24}') job_id=$(printf '%s' "$request_json" | jq -er '.id') poll_until_complete "upscaled" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/upscaled/$job_id" -o "restored.wav" ``` Related API endpoint documentation: - poll: https://neuralanalog.com/api-docs/status-object-type-object-id - Download: https://neuralanalog.com/api-docs/download-object-type-object-id - Master the restored audio: https://neuralanalog.com/api-docs/master-audio Product pages and guides: - Try audio restoration: https://neuralanalog.com/upscale-audio-mp3-to-wav - Read the restoration guide: https://neuralanalog.com/docs/improve-suno-ai-audio-quality ## Master music for streaming in your app POST /master-audio Send a song or stem. Choose the loudness target, genre, and output quality. Your app or agent gets a mastered WAV with louder, more balanced audio. Summary: Audio Mastering API Use this when: Use this API to add automatic mastering to a music app, upload flow, release tool, or batch script. It can master the original song, a restored version, or one stem. Set a target LUFS or use automatic loudness while keeping true peak below clipping. API behavior: Queue audio mastering for a track or stem. **Use this after the source audio is complete.** For imported links, poll `GET /status/audio/{audio_id}` before calling this endpoint. To master a restored version, pass `upscaled_id`; otherwise set `use_restored` to `true` to let Neural Analog use or create a restored source before mastering. The Audio Mastering API creates release-ready masters from original, upscaled, or stem sources with loudness, bit depth, and genre controls. The endpoint returns immediately with `id`, the mastered artifact ID: ```text POST /master-audio -> id GET /status/mastered/{id} GET /download/mastered/{id} ``` `target_lufs` controls integrated loudness. `genre` selects the mastering profile, with `modern` as the default release-ready profile. Workflow: 1. Send the song or stem: Pass an audio, restored, or stem ID with your loudness, genre, and output settings. 2. Wait for mastering: Save id and poll the mastering job until it finishes or fails. 3. Download the mastered WAV: Download the finished master and return it to the user or the next step in your app. Common use cases: - Master AI-generated songs: Restore compressed Suno, Udio, or other AI music first, then make it louder and more balanced. - Prepare tracks for streaming: Apply consistent loudness and tonal balance before users publish their music. - Master uploads automatically: Add a reusable mastering step to a web app, desktop tool, backend, or batch process. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - audio_id (required, string): Source audio asset ID to master. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - preset (optional, string): Selects the restoration model or repair process to run. Each preset supports its own parameters; fields that do not apply to the selected preset are ignored. Allowed: "universal_enhancer", "constant_bpm", "novasr", "flashsr", "dacvae", "declip", "dialogue_isolate", "denoise", "dereverb", "decrowd", "phantom_center", "audiosr", "apollo_voice", "lavasr", "reuse", "acestep_15_xl", "stable_audio_3", "universr", "aero". Default: "universal_enhancer". - stereo_mode (optional, string): Controls how stereo material is processed. single_pass keeps the stereo file together, mid_sides processes center and side content separately, left_right processes channels independently, and mono folds to mono. Supported by universal_enhancer, apollo_voice, universr, reuse, flashsr, audiosr, novasr, dacvae, aero, and lavasr. Other presets ignore this field. Allowed: "single_pass", "mid_sides", "left_right", "mono". Default: "single_pass". - frequency_cutoff (optional, integer): Sets the upper frequency boundary in hertz where a bandwidth-extension model starts rebuilding audio. Supported by audiosr and universr. AudioSR accepts 3000, 4000, 5000, 8000, 10000, 13000, or 16000. UniverSR accepts 4000, 6000, 8000, or 12000. Other presets ignore this field. Default: 13000. - model_name (optional, string): Selects the model variant used inside the restoration preset. Supported by denoise, aero, universr, acestep_15_xl, and stable_audio_3. Music variants are tuned for full mixes, voice variants for speech bandwidth, UniverSR variants for broad audio/vocal super-resolution, and ACE-Step/Stable Audio variants for prompt-guided remastering. Other presets choose their model from preset and ignore this field. Allowed: "denoise", "denoise_debleed", "music_musedb", "voice_4_16", "voice_8_16", "voice_8_24", "voice_12_48", "universr-audio", "universr-audio-finetune-v1", "universr-vocal", "acestep-v15-xl-turbo", "acestep-v15-xl-sft", "stable-audio-3-medium". Default: "music_musedb". - reconstruction_method (optional, string): Controls how generated high frequencies are combined with the source audio. Supported by audiosr and universr. For AudioSR, multiband_ensemble low-passes the original audio at frequency_cutoff minus 1000 Hz, high-passes the AudioSR output at the same crossover, then sums both bands. original_signal uses frequency_cutoff as a hard final spectrum boundary: original source bins below the cutoff and generated bins at or above it. For UniverSR, original preserves the legacy reconstruction path, while original_signal keeps the bandwidth-limited input for model conditioning but takes the final low-frequency bins from the original 48 kHz source signal. Other presets ignore this field. Allowed: "multiband_ensemble", "original", "original_signal". Default: "original". - strength (optional, number): Controls processing intensity from subtle cleanup to aggressive restoration. Higher values preserve less of the degraded source. Supported by acestep_15_xl and stable_audio_3. Other presets ignore this field. Default: 0.95. - prompt (optional, string): Describes the sound that a prompt-guided model should create from the source audio. Supported by acestep_15_xl and stable_audio_3. Other presets ignore this field. Keep the prompt under 256 characters. Default: "high quality remaster, studio recording, official release, CD quality.". Example: "clean studio master, full bandwidth, natural transients". - prompt_strength (optional, number): Controls how strongly Stable Audio 3 follows prompt relative to the reference audio. Higher values give the prompt more influence. Supported by stable_audio_3 only; other presets ignore this field. Accepts values from 0 to 10. Default: 1. - inpaint_regions (optional, array | null): Lists source time ranges to regenerate while preserving the rest of the input audio. Each range requires start and end times in seconds. Supported by stable_audio_3 only; other presets ignore this field. Omit it to run an ordinary audio-to-audio remix. Example: [{"end":8,"start":4}]. - stem_id (optional, string | null): Optional source stem ID. Omit to master the full audio file. Example: "abf8a992-1c4e-4935-93f0-197116e77e49". - use_restored (optional, boolean): Controls whether restoration runs before mastering. true uses an existing restored version or queues restoration automatically; false masters the selected source directly. Default: true. - upscaled_id (optional, string | null): Specific restored version to use as the mastering source. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - source_mastered_id (optional, string | null): Specific mastered artifact to use as the mastering source. Example: "f5db8e4b-2e74-4198-a8de-0c3a398620e9". - source_temporary_mix_key (optional, string | null): Short-lived Current Main Mix or Current All Stems Mix R2 source key. - selection (optional, object | null): Limits mastering to a start and end time in seconds. Omit it to master the full selected source. Example: {"end":42,"start":12.5}. - bit_depth (optional, integer): Output WAV bit depth for the mastered audio. Allowed: 16, 24. Default: 24. - hq_streaming_format (optional, string): Selects the compressed format generated for browser playback and streaming alongside the mastered WAV output. Allowed: "aac", "mp3", "flac". Default: "aac". - target_lufs (optional, number): Sets the integrated loudness target in LUFS for the mastered output, or 'auto' to maximize loudness up to -1 dBTP true peak. Default: -14. - genre (optional, string): Selects the tonal mastering profile. modern is the default balanced profile for contemporary releases. Default: "modern". Model and parameter reference: ### Choose how the master should sound Selector field: `genre`. Models and API values: - `genre="modern"` (Modern): Balanced, clean sound suitable for most contemporary styles. - Parameters: none. - `genre="hiphop"` (Hip Hop): Deep bass and punchy drums for maximum impact. - Parameters: none. - `genre="techno"` (Techno): Driving low-end and crisp highs for club systems. - Parameters: none. - `genre="rock"` (Rock): Dynamic mid-range presence and controlled saturation. - Parameters: none. - `genre="rnb"` (R&B): Smooth, warm tones with polished vocals. - Parameters: none. - `genre="trap"` (Trap): Heavy 808s and sharp transients. - Parameters: none. Success responses: - 200: Successful Response - id (required, string): ID of the queued mastered audio version. Example: "f5db8e4b-2e74-4198-a8de-0c3a398620e9". - status (required, string): Queueing status for the mastering job. Example: "processing". - message (required, string): Human-readable queueing result. Example: "Mastering queued". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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}/master-audio`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ "audio_id": "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a", "use_restored": true, "target_lufs": -14, "genre": "modern", "bit_depth": 24 }), }); if (!requestResponse.ok) { throw new Error(`Mastering request failed with ${requestResponse.status}`); } const result = await requestResponse.json(); const jobId = result["id"]; const status = await waitForCompletion("mastered", jobId); const downloadResponse = await fetch( `${API_URL}/download/mastered/${jobId}`, { headers: { "X-API-Key": API_KEY }, redirect: "follow" }, ); if (!downloadResponse.ok) { throw new Error(`Download failed with ${downloadResponse.status}`); } await writeFile("mastered.wav", Buffer.from(await downloadResponse.arrayBuffer())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/master-audio", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'use_restored': True, 'target_lufs': -14, 'genre': 'modern', 'bit_depth': 24}, ) request_response.raise_for_status() result = request_response.json() job_id = result["id"] status = wait_for_completion("mastered", job_id) download_response = requests.get( f"{API_URL}/download/mastered/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("mastered.wav", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/master-audio" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","use_restored":true,"target_lufs":-14,"genre":"modern","bit_depth":24}') job_id=$(printf '%s' "$request_json" | jq -er '.id') poll_until_complete "mastered" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/mastered/$job_id" -o "mastered.wav" ``` Related API endpoint documentation: - poll: https://neuralanalog.com/api-docs/status-object-type-object-id - Download the completed master: https://neuralanalog.com/api-docs/download-object-type-object-id Product pages and guides: - Try automatic mastering: https://neuralanalog.com/auto-mastering - Read the mastering guide: https://neuralanalog.com/docs/auto-mastering-ai-music ## Split a song into vocals, drums, bass, and other stems POST /create-stems Send a song and choose the stems you need. Use a preset for vocals, drums, bass, guitar, and other common parts, or describe a custom sound. Your app or agent gets separate WAV files. Summary: Stem Splitting API Use this when: Use this API to build a vocal remover, remix tool, backing-track maker, practice app, sampling workflow, or sound-removal feature. Choose a fixed 2-, 4-, 6-, or 53-stem preset for reusable output names. Use SAM Audio when the user needs to describe a less common instrument, noise, or sound. API behavior: Queue stem splitting for an audio asset or an existing stem. **Use this after the source has finished importing or processing.** For a full track, pass an `audio_id` returned by `/from-link` or upload flow after `GET /status/audio/{audio_id}` reports completion. To split an existing stem further, pass `stem_id` instead. The Stem Splitting API separates original, upscaled, mastered, or stem sources into vocals, drums, bass, instrumental, and other configured stem layouts for downstream download or mastering. Source selection rules: ```text - `audio_id`: split the original imported/uploaded track. - `upscaled_id`: split a restored version of that audio. - `mastered_id`: split a mastered version of that audio. - `stem_id`: split an existing stem; this takes priority over `audio_id`. ``` The response returns `creation_id`, which identifies the stem split job. Poll `GET /status/stem_split/{creation_id}` until it is complete. Completed stems can then be downloaded with `/download/stem/{stem_id}` or packaged with `/download-archive`. Workflow: 1. Choose the stems: Select a preset or describe the instrument, voice, noise, or sound you want to isolate. 2. Wait for stem separation: Send the audio ID, save creation_id, and poll the stem-splitting job until it finishes. 3. Download separate WAV files: Download each stem separately or package the selected stems into one ZIP archive. Common use cases: - Build a vocal remover: Return vocal and instrumental WAV files for karaoke, remixing, practice, or sampling. - Create remix and production stems: Give users separate drums, bass, vocals, guitar, and instrument tracks inside your software. - Remove an unwanted sound: Isolate crowd noise, reverb, drums, effects, or another described sound from a recording. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - preset (required, string): Selects which stems or cleanup result the separation job returns. Some presets support an additional model_name variant; incompatible variants are rejected. Allowed: "acapella", "instrumental", "2_tracks", "2_tracks_leap", "4_tracks", "6_tracks", "5_drums_tracks", "2_tracks_drums", "custom", "lead_back", "duet", "modern_bowed_strings", "guitar", "synth_lead", "mvsep_mega_53", "denoise", "denoise_debleed", "dereverb", "decrowd", "decrowd_mdx", "phantom_center", "5_1_upmix". - audio_id (optional, string | null): Source audio asset to split. Provide either audio_id or stem_id. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - stem_id (optional, string | null): Existing stem to split further. When provided with audio_id, stem_id takes priority. Example: "abf8a992-1c4e-4935-93f0-197116e77e49". - model_name (optional, string | null): Selects the model variant used by a compatible stem preset. For 2_tracks, use deux or leap. For denoise, use denoise or denoise_debleed. For decrowd, use decrowd or decrowd_mdx. Other presets reject this field. Allowed: "deux", "leap", "denoise", "denoise_debleed", "decrowd", "decrowd_mdx". - bit_depth (optional, integer): Output WAV bit depth for generated stems. Allowed: 16, 24. Default: 24. - hq_streaming_format (optional, string): Selects the compressed format generated for browser playback and streaming alongside the WAV stem output. Allowed: "aac", "mp3", "flac". Default: "aac". - prompt (optional, string | null): Describes the sound SAM Audio should isolate, for example 'lead vocal' or 'snare and kick'. Supported when preset is custom; other stem presets ignore this field. Long prompts are trimmed before validation. Example: "lead vocal". - sam_model (optional, string): Selects the SAM Audio model size used for prompt-guided stem extraction. Supported when preset is custom; other stem presets ignore this field. Allowed: "sam-audio-small", "sam-audio-base", "sam-audio-large". Default: "sam-audio-base". - stereo_mode (optional, string): Controls how SAM Audio processes stereo material. mono is fastest, mid_sides preserves center/side detail, and left_right processes channels separately. Supported when preset is custom; other stem presets ignore this field. Allowed: "mono", "mid_sides", "left_right". Default: "mono". - spans (optional, array | null): Provides optional start and end times where SAM Audio should focus on the prompted sound. Supported when preset is custom; other stem presets ignore this field. Omit it to split without time hints. Example: [{"end":42,"start":12.5}]. - selection (optional, object | null): Optional source region to process. When provided, the backend trims the source to this region before running separation. Example: {"end":42,"start":12.5}. - upscaled_id (optional, string | null): Restored version to use as the stem separation source. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - mastered_id (optional, string | null): Mastered version to use as the stem separation source. Example: "f5db8e4b-2e74-4198-a8de-0c3a398620e9". - temporary_mix_key (optional, string | null): Short-lived Current Main Mix or Current All Stems Mix R2 source key. - restoration_params (optional, object | null): Queues restoration for generated stems as part of the same workflow. The nested restoration preset determines which nested parameters are used. Ordinary stem splitting ignores this field. Example: {"preset":"universal_enhancer","strength":0.8}. - stem_processing (optional, object | null): Queues one operation for every generated, non-silent stem. Supports restoration, mastering, and audio-to-MIDI transcription. Omit it to return the separated stems without additional processing. restoration_params remains supported as a legacy restoration-only alias. - selected_stems (optional, array | null): Names the instrument outputs to keep from the 53-stem model. Supported when preset is mvsep_mega_53; other presets ignore this field. The residual 'other' stem is always generated from the original audio minus the selected outputs. Example: ["drums","vocals","bass","piano","strings","piano_synth","guitar","other"]. Model and parameter reference: ### Choose the stems you want Selector field: `preset`. Models and API values: - `preset="4_tracks"` (4 stems): Bass, Drums, Vocals, Others - Parameters: none. - `preset="6_tracks"` (6 stems): Bass, Drums, Vocals, Guitar, Piano, Others - Parameters: none. - `preset="mvsep_mega_53"` (53 stems (MVSEP Mega)): Ultra-granular instrument model. Select which generated instrument stems to keep; Other is always included as the residual between the original audio and the selected generated stems. For higher quality, use the specialized models. Consumes 3x the processed audio minutes. - Parameters: - `selected_stems` (Instrument stems to keep, Array | null): Names the instrument outputs to keep from the 53-stem model. Supported when preset is mvsep_mega_53; other presets ignore this field. The residual 'other' stem is always generated from the original audio minus the selected outputs. - Example: ["drums","vocals","bass","piano","strings","piano_synth","guitar","other"]. - `preset="modern_bowed_strings"` (Modern Bowed Strings): Strings, Other - Parameters: none. - `preset="guitar"` (Guitar): Guitar, Other - Parameters: none. - `preset="synth_lead"` (Synth Lead): Synth lead, Other - Parameters: none. - `preset="2_tracks"` (2 tracks): Vocals (acapella), Instrumental (karaoke version) - Parameters: - `model_name` (Model variant, string | null): Selects the model variant used by a compatible stem preset. For 2_tracks, use deux or leap. For denoise, use denoise or denoise_debleed. For decrowd, use decrowd or decrowd_mdx. Other presets reject this field. - Allowed values: `deux` (Deux model) **Recommended**, `leap` (Leap Xe). - `deux`: Single Deux vocal/instrumental separator. - `leap`: Runs separate Leap Xe vocal and instrumental BS-Roformer models. - `preset="lead_back"` (Lead / Backing Vocals): Lead vocals, backing vocals - Parameters: none. - `preset="duet"` (Duet Singers): Singer 1, Singer 2 - Parameters: none. - `preset="2_tracks_drums"` (Isolate Drums): No drums, Drums. Special model to separate drums from instrumental. Preserve high fullness in drums and instrumental. - Parameters: none. - `preset="5_drums_tracks"` (5 drums tracks): Split drums into Kick, Snare, Toms, Hi-hats, Cymbals - Parameters: none. - `preset="dereverb"` (Dereverb): Remove reverberation, delay, and echo - Parameters: none. - `preset="denoise"` (Denoise): Remove background noise from music or vocal tracks - Parameters: - `model_name` (Model variant, string | null): Selects the model variant used by a compatible stem preset. For 2_tracks, use deux or leap. For denoise, use denoise or denoise_debleed. For decrowd, use decrowd or decrowd_mdx. Other presets reject this field. - Allowed values: `denoise` (Denoise model) **Recommended**, `denoise_debleed` (Denoise and Debleed model). - `denoise`: Removes background noise. - `denoise_debleed`: Removes background noise and source bleed. - `preset="decrowd"` (Fast Decrowd): Quickly remove crowd noise from live recordings - Parameters: - `model_name` (Model variant, string | null): Selects the model variant used by a compatible stem preset. For 2_tracks, use deux or leap. For denoise, use denoise or denoise_debleed. For decrowd, use decrowd or decrowd_mdx. Other presets reject this field. - Allowed values: `decrowd` (Melband Roformer) **Recommended**, `decrowd_mdx` (MDX Net). - `decrowd`: Most recent recent crowd-noise separator. Runs this only on Vocals stems to get more precise results. - `decrowd_mdx`: Older crowd-noise separator. - `preset="phantom_center"` (Keep Only Center Mono): Extracts the "phantom center", the content that should be mono in a track. Use this for: bass, kick drums, podcast voice. Removes phaser, chorus, or flanger from instrument stems. Good for mixing. - Parameters: none. - `preset="5_1_upmix"` (5.1 Upmix): Generate: LR (Front stereo), S (Sides stereo), LFE (Sub frequencies), C (Center front channel) - Parameters: none. - `preset="custom"` (SAM Audio custom separation): Describe the sound to isolate and receive separate with-prompt and without-prompt WAV files. - Parameters: - `prompt` (Sound prompt, string | null): Describes the sound SAM Audio should isolate, for example 'lead vocal' or 'snare and kick'. Supported when preset is custom; other stem presets ignore this field. Long prompts are trimmed before validation. - Example: "lead vocal". - `sam_model` (SAM Audio model size, string): Selects the SAM Audio model size used for prompt-guided stem extraction. Supported when preset is custom; other stem presets ignore this field. - Allowed values: `sam-audio-small`, `sam-audio-base` **Default**, `sam-audio-large`. - `stereo_mode` (Stereo handling, string): Controls how SAM Audio processes stereo material. mono is fastest, mid_sides preserves center/side detail, and left_right processes channels separately. Supported when preset is custom; other stem presets ignore this field. - Allowed values: `mono` **Default**, `mid_sides`, `left_right`. - `spans` (Prompt hint ranges, Array<{ start: number; end: number }> | null): Provides optional start and end times where SAM Audio should focus on the prompted sound. Supported when preset is custom; other stem presets ignore this field. Omit it to split without time hints. - Example: [{"end":42,"start":12.5}]. Success responses: - 200: Successful Response - status (required, string): Status after the stem job is queued. Example: "processing". - message (required, string): Human-readable queueing result. Example: "Stem separation queued". - audio_id (required, string): Source audio asset ID. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - user_id (required, string): User that owns the job. Example: "2fe9c052-e34f-43b7-9ad5-5186d31cb7ec". - creation_id (required, string): Stem split job ID. Example: "18d67d83-c9f6-4d7f-bb72-09e40c62671e". - audio_stems (optional, array): No description provided. - upscaled_audios (optional, array): No description provided. - mastered_audios (optional, array): No description provided. - transcriptions (optional, array): No description provided. Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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}/create-stems`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ "audio_id": "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a", "preset": "4_tracks", "bit_depth": 24 }), }); if (!requestResponse.ok) { throw new Error(`Stem separation request failed with ${requestResponse.status}`); } const result = await requestResponse.json(); const jobId = result["creation_id"]; const status = await waitForCompletion("stem_split", jobId); for (const artifact of result["audio_stems"]) { const artifactId = artifact["stem_id"]; const response = await fetch( `${API_URL}/download/stem/${artifactId}`, { headers: { "X-API-Key": API_KEY }, redirect: "follow" }, ); if (!response.ok) { throw new Error(`Download failed with ${response.status}`); } await writeFile(`${artifactId}.wav`, Buffer.from(await response.arrayBuffer())); } ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/create-stems", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'preset': '4_tracks', 'bit_depth': 24}, ) request_response.raise_for_status() result = request_response.json() job_id = result["creation_id"] status = wait_for_completion("stem_split", job_id) for artifact in result["audio_stems"]: artifact_id = artifact["stem_id"] response = requests.get( f"{API_URL}/download/stem/{artifact_id}", headers=HEADERS, allow_redirects=True, ) response.raise_for_status() with open(f"{artifact_id}.wav", "wb") as output: output.write(response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/create-stems" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","preset":"4_tracks","bit_depth":24}') job_id=$(printf '%s' "$request_json" | jq -er '.creation_id') poll_until_complete "stem_split" "$job_id" printf '%s' "$request_json" | jq -er '.audio_stems[].stem_id' | while read -r artifact_id; do curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/stem/$artifact_id" -o "$artifact_id.wav" done ``` Related API endpoint documentation: - poll: https://neuralanalog.com/api-docs/status-object-type-object-id - Package stems into an archive: https://neuralanalog.com/api-docs/download-archive Product pages and guides: - Try the stem splitter: https://neuralanalog.com/ai-stem-splitter - Read the stem separation guide: https://neuralanalog.com/docs/high-quality-stem-splitting ## Convert songs and instrument stems to MIDI POST /transcribe Send a full song or an isolated instrument stem. Your app or agent gets editable MIDI notes for arranging, practice, playback, analysis, or sound replacement. Summary: Audio to MIDI Transcription API Use this when: Use this API to build an audio-to-MIDI converter, transcription tool, practice app, arrangement assistant, or DAW feature. Split a full song into stems first when users need separate bass, drum, vocal, and instrument MIDI. MuScriptor supports automatic or selected instruments and optional note quantization. API behavior: Queue audio-to-MIDI transcription on a T4 GPU. Workflow: 1. Choose the song or stem: Pass the audio ID and optionally select one isolated stem or the instruments to detect. 2. Wait for transcription: Save id and poll the MIDI transcription job until it finishes or fails. 3. Download the MIDI: Download the .mid file and open it in your app, DAW, piano roll, or notation workflow. Common use cases: - Learn an instrument part: Turn an isolated bass, drum, vocal, or instrument stem into notes users can inspect and practice. - Reorchestrate a song: Import the MIDI into a DAW, change instruments, correct notes, and reshape the arrangement. - Replace sounds with a VST: Use the detected notes to trigger drums, synths, samplers, or another instrument in your software. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - audio_id (required, string): Identifies the parent audio to transcribe. - stem_id (optional, string | null): Selects one stem from the parent audio as the transcription source. - upscaled_id (optional, string | null): Selects a restored version of the parent audio as the source. - mastered_id (optional, string | null): Selects a mastered version of the parent audio as the source. - temporary_mix_key (optional, string | null): Short-lived Current Main Mix or Current All Stems Mix R2 source key. - selection (optional, object | null): Limits transcription to a start and end time in seconds. Omit it to transcribe the full selected source. - model (optional, string): Selects the MuScriptor large audio-to-MIDI model. Default: "muscriptor-large". - instrument_mode (optional, string | null): Controls how instrument tracks are created. auto detects instruments, select uses the instruments list as guidance, and combine_melodic combines melodic parts. Omit it to infer the mode from instruments. Allowed: "auto", "select", "combine_melodic". - instruments (optional, array): Guides which instrument tracks MuScriptor should transcribe. Leave the list empty to detect instruments automatically. Accepts up to 128 names, each between 1 and 64 characters. Example: ["piano","bass"]. - quantize_precision (optional, string | null): Sets the timing grid for MIDI note starts and releases. Use null to preserve the timing detected by the transcription model. Allowed: "1/4", "1/8", "1/8T", "1/16", "1/16T", "1/32", "1/32T". Model and parameter reference: ### Choose how the MIDI tracks are created Selector field: `model`. Models and API values: - `model="muscriptor-large"` (MuScriptor large): Transcribes polyphonic audio into instrument-colored MIDI notes. - Parameters: - `instrument_mode` (Instrument track mode, string | null): Controls how instrument tracks are created. auto detects instruments, select uses the instruments list as guidance, and combine_melodic combines melodic parts. Omit it to infer the mode from instruments. - Allowed values: `auto`, `select`, `combine_melodic`. - `instruments` (Instrument guidance, Array): Guides which instrument tracks MuScriptor should transcribe. Leave the list empty to detect instruments automatically. Accepts up to 128 names, each between 1 and 64 characters. - Supported instruments: `electric_bass` (Bass), `acoustic_bass` (Acoustic Bass), `drums` (Drums), `acoustic_guitar` (Acoustic Guitar), `clean_electric_guitar` (Clean Electric Guitar), `distorted_electric_guitar` (Distorted Electric Guitar), `acoustic_piano` (Acoustic Piano), `electric_piano` (Electric Piano), `organ` (Organ), `synth_lead` (Synth Lead), `synth_pad` (Synth Pad), `synth_strings` (Synth Strings), `orchestra_hit` (Orchestra Hit), `string_ensemble` (String Ensemble), `violin` (Violin), `viola` (Viola), `cello` (Cello), `contrabass` (Contrabass), `orchestral_harp` (Orchestral Harp), `voice` (Voice), `chromatic_percussion` (Xylophone), `timpani` (Timpani), `brass_section` (Brass Section), `trumpet` (Trumpet), `trombone` (Trombone), `french_horn` (French Horn), `tuba` (Tuba), `soprano_and_alto_sax` (Soprano & Alto Saxophone), `tenor_sax` (Tenor Saxophone), `baritone_sax` (Baritone Saxophone), `flutes` (Flutes), `clarinet` (Clarinet), `oboe` (Oboe), `english_horn` (English Horn), `bassoon` (Bassoon). - `quantize_precision` (Note quantization, string | null): Sets the timing grid for MIDI note starts and releases. Use null to preserve the timing detected by the transcription model. - Allowed values: `1/4`, `1/8`, `1/8T`, `1/16`, `1/16T`, `1/32`, `1/32T`. - `selection` (Source time range, { start: number; end: number } | null): Limits transcription to a start and end time in seconds. Omit it to transcribe the full selected source. Success responses: - 200: Successful Response - id (required, string): ID of the queued transcription. Example: "d66cf940-bf26-45bb-80f7-332f26b6859a". - status (required, string): Queueing status for the transcription job. Example: "starting". - message (required, string): Human-readable queueing result. Example: "MIDI transcription started successfully". Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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}/transcribe`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ "audio_id": "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a", "model": "muscriptor-large", "instrument_mode": "auto", "quantize_precision": "1/16" }), }); if (!requestResponse.ok) { throw new Error(`Transcription request failed with ${requestResponse.status}`); } const result = await requestResponse.json(); const jobId = result["id"]; const status = await waitForCompletion("transcription", jobId); const downloadResponse = await fetch( `${API_URL}/download/transcription/${jobId}`, { headers: { "X-API-Key": API_KEY }, redirect: "follow" }, ); if (!downloadResponse.ok) { throw new Error(`Download failed with ${downloadResponse.status}`); } await writeFile("transcription.mid", Buffer.from(await downloadResponse.arrayBuffer())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/transcribe", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'model': 'muscriptor-large', 'instrument_mode': 'auto', 'quantize_precision': '1/16'}, ) request_response.raise_for_status() result = request_response.json() job_id = result["id"] status = wait_for_completion("transcription", job_id) download_response = requests.get( f"{API_URL}/download/transcription/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("transcription.mid", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/transcribe" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","model":"muscriptor-large","instrument_mode":"auto","quantize_precision":"1/16"}') job_id=$(printf '%s' "$request_json" | jq -er '.id') poll_until_complete "transcription" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/transcription/$job_id" -o "transcription.mid" ``` Related API endpoint documentation: - poll: https://neuralanalog.com/api-docs/status-object-type-object-id - Download the completed MIDI: https://neuralanalog.com/api-docs/download-object-type-object-id - Separate instruments first: https://neuralanalog.com/api-docs/create-stems Product pages and guides: - Preview MIDI workflows: https://neuralanalog.com/midi-to-mp3 ## Download tracks or stems as one ZIP POST /download-archive Choose the original songs, restored WAVs, masters, or stems your user needs. The API creates one ZIP and returns a temporary download link, or sends large exports by email. Summary: Download Archive Use this when: Use this endpoint to build library export, batch download, project handoff, or stem-pack delivery into your app. Wait for every selected file to finish first. Request full-track versions and stem versions separately. API behavior: Package completed tracks or stems into one temporary zip archive. **Use this after the requested versions are complete.** For example, poll `/status/audio/{audio_id}`, `/status/upscaled/{id}`, `/status/mastered/{id}`, or `/status/stem_split/{creation_id}` before requesting the corresponding archive versions. Track and stem archive versions are separate requests: ```json {"id": "audio-id", "versions": ["original", "mastered"], "format": "wav"} ``` ```json {"id": "audio-id", "versions": ["original_stems"], "format": "wav"} ``` The response usually contains `download_url`. For large archives, the API may return `email_notification_queued: true`; in that case archive creation continues in the background and the signed link is delivered by email. Workflow: 1. Wait for every file: Poll each download, restoration, master, or stem job before creating the ZIP. 2. Choose files and format: Send one or more audio IDs, the versions to include, and the output format. 3. Download the ZIP: Follow the signed URL or handle the queued email delivery for a large export. Common use cases: - Export a user’s music library: Package multiple downloaded or uploaded tracks into one file for backup or migration. - Deliver a stem pack: Return all requested vocal, drum, bass, and instrument stems as one ZIP. - Deliver processed versions: Bundle the original, restored, and mastered versions for a project handoff. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. JSON request body: - versions (required, array): Artifact versions to include. Use original/restored/mastered for full-track audio and original_stems/restored_stems/mastered_stems for stem archives. Example: ["original","mastered"]. - id (optional, string | null): Single audio asset ID to package. Example: "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a". - ids (optional, array | null): Audio asset IDs to package into one zip archive. Example: ["6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","0d8ea9f2-ae8c-4af7-b73e-4b241ae5ce88"]. - stem_ids (optional, array | null): Optional stem IDs to include when downloading stem versions. Example: ["abf8a992-1c4e-4935-93f0-197116e77e49"]. - stem_selections (optional, array | null): Exact per-stem versions to include when downloading stem archives. Example: [{"mastered_id":"f5db8e4b-2e74-4198-a8de-0c3a398620e9","stem_id":"abf8a992-1c4e-4935-93f0-197116e77e49","version":"mastered"}]. - format (optional, string): Default requested archive format for stem versions. Allowed: "wav", "flac", "mp3", "m4a". Default: "wav". - original_format (optional, string | null): No description provided. Allowed: "wav", "flac", "mp3", "m4a". - restored_format (optional, string | null): No description provided. Allowed: "wav", "flac", "mp3", "m4a". - mastered_format (optional, string | null): No description provided. Allowed: "wav", "flac", "mp3", "m4a". Success responses: - 200: Successful Response - delivery_method (required, string): How the archive will be delivered: immediately through download_url or asynchronously by email. Allowed: "download_url", "email". - download_url (optional, string | null): Temporary URL for the generated zip archive. Null when archive creation continues in the background and the user will be emailed. Example: "https://storage.example.com/neuralanalog/archive.zip". - expires_in_seconds (optional, integer): How long the generated zip URL remains valid. Default: 86400. - email_notification_queued (optional, boolean): Whether the archive is still being created and a download email has been queued. Default: false. - email_notification_threshold_seconds (optional, integer | null): Server-side zipping duration threshold that triggers email delivery. Example: 30. - archive_incomplete (optional, boolean): Whether some requested files were skipped because the archive hit size or processing limits. Default: false. Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript import { writeFile } from "node:fs/promises"; const API_URL = "https://api.neuralanalog.com"; const API_KEY = process.env.NEURALANALOG_API_KEY; const audioId = "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a"; const restoredId = "d66cf940-bf26-45bb-80f7-332f26b6859a"; const masteredId = "f5db8e4b-2e74-4198-a8de-0c3a398620e9"; 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)); } } await Promise.all([ waitForCompletion("audio", audioId), waitForCompletion("upscaled", restoredId), waitForCompletion("mastered", masteredId), ]); const response = await fetch(`${API_URL}/download-archive`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ id: audioId, versions: ["original", "restored", "mastered"], format: "wav", }), }); if (!response.ok) { throw new Error(`Archive request failed with ${response.status}`); } const archive = await response.json(); if (archive.delivery_method === "email") { console.log("Archive creation continues in the background; check your email."); } else { const download = await fetch(archive.download_url, { redirect: "follow" }); if (!download.ok) { throw new Error(`Archive download failed with ${download.status}`); } await writeFile("neuralanalog-archive.zip", Buffer.from(await download.arrayBuffer())); } ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} audio_id = "6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a" restored_id = "d66cf940-bf26-45bb-80f7-332f26b6859a" mastered_id = "f5db8e4b-2e74-4198-a8de-0c3a398620e9" def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) wait_for_completion("audio", audio_id) wait_for_completion("upscaled", restored_id) wait_for_completion("mastered", mastered_id) response = requests.post( f"{API_URL}/download-archive", headers=HEADERS, json={ "id": audio_id, "versions": ["original", "restored", "mastered"], "format": "wav", }, ) response.raise_for_status() archive = response.json() if archive["delivery_method"] == "email": print("Archive creation continues in the background; check your email.") else: download = requests.get(archive["download_url"], allow_redirects=True) download.raise_for_status() with open("neuralanalog-archive.zip", "wb") as output: output.write(download.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" audio_id="6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a" restored_id="d66cf940-bf26-45bb-80f7-332f26b6859a" mastered_id="f5db8e4b-2e74-4198-a8de-0c3a398620e9" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } poll_until_complete "audio" "$audio_id" poll_until_complete "upscaled" "$restored_id" poll_until_complete "mastered" "$mastered_id" archive_json=$(curl -fsS -X POST "$API_URL/download-archive" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d "{\\"id\\":\\"$audio_id\\",\\"versions\\":[\\"original\\",\\"restored\\",\\"mastered\\"],\\"format\\":\\"wav\\"}") if [ "$(printf '%s' "$archive_json" | jq -r '.delivery_method')" = "email" ]; then printf '%s\\n' "Archive creation continues in the background; check your email." else download_url=$(printf '%s' "$archive_json" | jq -er '.download_url') curl -fsSL "$download_url" -o neuralanalog-archive.zip fi ``` Related API endpoint documentation: - Confirm every version is ready: https://neuralanalog.com/api-docs/status-object-type-object-id - Download one file instead: https://neuralanalog.com/api-docs/download-object-type-object-id Product pages and guides: - Review processing usage: https://neuralanalog.com/settings#usage ## Download an audio or MIDI file by ID GET /download/{object_type}/{object_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. Summary: Download Object Use this when: 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. API behavior: Download a completed audio artifact. **Use this only after status polling reports completion.** The endpoint does not stream bytes itself; it returns a `307` redirect to a temporary signed storage URL. Typical flow: ```text GET /status/upscaled/{id} -> is_complete: true GET /download/upscaled/{id} -> 307 Location: signed file URL ``` Use `object_type=audio` for the original imported/uploaded file, `stem` for an individual stem, `upscaled` for restored audio, and `mastered` for mastered audio. Workflow: 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: - 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. Authorization: - Send `X-API-Key: $NEURALANALOG_API_KEY` with every request. Path/query parameters: - object_type (required, path, string): Artifact collection to download. Common values are audio, stem, upscaled, mastered, and transcription. - object_id (required, path, string): Identifier for the requested artifact in the selected object_type. - format (optional, query, string): Preferred output format when the artifact supports format selection. - track (optional, query, boolean): Whether this request should count as a user download. Success responses: - 307: Temporary redirect to the signed artifact download URL. Validation responses: - 422: Validation Error - detail (optional, array): No description provided. JavaScript (Node.js) example: ```javascript 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())); ``` Python example: ```python import os import time import requests API_URL = "https://api.neuralanalog.com" HEADERS = {"X-API-Key": os.environ["NEURALANALOG_API_KEY"]} def wait_for_completion(object_type, object_id): while True: response = requests.get( f"{API_URL}/status/{object_type}/{object_id}", headers=HEADERS, ) response.raise_for_status() status = response.json() if status["is_failed"]: raise RuntimeError( status.get("error_message") or f"{object_type} processing failed" ) if status["is_complete"]: return status time.sleep(5) request_response = requests.post( f"{API_URL}/upscale-audio", headers=HEADERS, json={'audio_id': '6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a', 'preset': 'universal_enhancer', 'bit_depth': 24}, ) request_response.raise_for_status() result = request_response.json() job_id = result["id"] status = wait_for_completion("upscaled", job_id) download_response = requests.get( f"{API_URL}/download/upscaled/{job_id}", headers=HEADERS, allow_redirects=True, ) download_response.raise_for_status() with open("restored.wav", "wb") as output: output.write(download_response.content) ``` cURL example: ```bash API_URL="https://api.neuralanalog.com" poll_until_complete() { object_type="$1" object_id="$2" while true; do status_json=$(curl -fsS \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ "$API_URL/status/$object_type/$object_id") if [ "$(printf '%s' "$status_json" | jq -r '.is_failed')" = "true" ]; then printf '%s' "$status_json" | jq -r '.error_message // "Processing failed"' >&2 return 1 fi [ "$(printf '%s' "$status_json" | jq -r '.is_complete')" = "true" ] && return sleep 5 done } request_json=$(curl -fsS -X POST "$API_URL/upscale-audio" \ -H "X-API-Key: $NEURALANALOG_API_KEY" \ -H "Content-Type: application/json" \ -d '{"audio_id":"6c62f8e7-02a3-48c0-a5b5-5de87ed9c31a","preset":"universal_enhancer","bit_depth":24}') job_id=$(printf '%s' "$request_json" | jq -er '.id') poll_until_complete "upscaled" "$job_id" curl -fsSL -H "X-API-Key: $NEURALANALOG_API_KEY" "$API_URL/download/upscaled/$job_id" -o "restored.wav" ``` Related API endpoint documentation: - Poll before downloading: https://neuralanalog.com/api-docs/status-object-type-object-id - Download several files as a ZIP: https://neuralanalog.com/api-docs/download-archive - Review the complete API flow: https://neuralanalog.com/api-docs