curl --request POST \
--url https://api.recoupable.com/api/songs/analyze \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"audio_url": "https://example.com/song.mp3",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": false
}
'import requests
url = "https://api.recoupable.com/api/songs/analyze"
payload = {
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"audio_url": "https://example.com/song.mp3",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
preset: 'catalog_metadata',
prompt: 'Describe the genre, tempo, and mood of this track.',
audio_url: 'https://example.com/song.mp3',
max_new_tokens: 512,
temperature: 0.7,
top_p: 0.9,
do_sample: false
})
};
fetch('https://api.recoupable.com/api/songs/analyze', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.recoupable.com/api/songs/analyze",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'preset' => 'catalog_metadata',
'prompt' => 'Describe the genre, tempo, and mood of this track.',
'audio_url' => 'https://example.com/song.mp3',
'max_new_tokens' => 512,
'temperature' => 0.7,
'top_p' => 0.9,
'do_sample' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.recoupable.com/api/songs/analyze"
payload := strings.NewReader("{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.recoupable.com/api/songs/analyze")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.recoupable.com/api/songs/analyze")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"preset": "catalog_metadata",
"response": "<unknown>",
"report": {},
"elapsed_seconds": 123
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}Analyze Songs
Analyze music using a state-of-the-art Audio Language Model that listens directly to the audio waveform. Unlike text-based AI, this model processes the actual sound — identifying harmony, structure, timbre, lyrics, and cultural context through deep music understanding. Supports audio up to 20 minutes (MP3, WAV, FLAC). Two modes: (1) Presets — pass a preset name like catalog_metadata, mood_tags, or full_report for structured, optimized output. (2) Custom prompt — pass a prompt for free-form questions. The full_report preset runs all 13 presets in parallel and returns a comprehensive music intelligence report. Use GET /api/songs/analyze/presets to list available presets.
curl --request POST \
--url https://api.recoupable.com/api/songs/analyze \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"audio_url": "https://example.com/song.mp3",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": false
}
'import requests
url = "https://api.recoupable.com/api/songs/analyze"
payload = {
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"audio_url": "https://example.com/song.mp3",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
preset: 'catalog_metadata',
prompt: 'Describe the genre, tempo, and mood of this track.',
audio_url: 'https://example.com/song.mp3',
max_new_tokens: 512,
temperature: 0.7,
top_p: 0.9,
do_sample: false
})
};
fetch('https://api.recoupable.com/api/songs/analyze', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.recoupable.com/api/songs/analyze",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'preset' => 'catalog_metadata',
'prompt' => 'Describe the genre, tempo, and mood of this track.',
'audio_url' => 'https://example.com/song.mp3',
'max_new_tokens' => 512,
'temperature' => 0.7,
'top_p' => 0.9,
'do_sample' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.recoupable.com/api/songs/analyze"
payload := strings.NewReader("{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.recoupable.com/api/songs/analyze")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.recoupable.com/api/songs/analyze")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\n \"audio_url\": \"https://example.com/song.mp3\",\n \"max_new_tokens\": 512,\n \"temperature\": 0.7,\n \"top_p\": 0.9,\n \"do_sample\": false\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"preset": "catalog_metadata",
"response": "<unknown>",
"report": {},
"elapsed_seconds": 123
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}Authorizations
Your Recoup API key. Learn more.
Body
Music analysis request
Provide exactly one of preset or prompt. Use preset for structured analysis workflows, or prompt for free-form questions.
Name of a curated analysis preset. Use instead of prompt for structured, optimized output. The 'full_report' preset runs all 13 presets in parallel and returns a comprehensive report. See List Analyze Presets for the full list of available presets.
catalog_metadata, mood_tags, lyric_transcription, mix_feedback, song_description, music_theory, similar_artists, sample_detection, sync_brief_match, audience_profile, content_advisory, playlist_pitch, artist_development_notes, full_report "catalog_metadata"
Text prompt or question about the music
1 - 24000"Describe the genre, tempo, and mood of this track."
Public URL to an audio file (MP3, WAV, or FLAC — up to 20 minutes)
"https://example.com/song.mp3"
Maximum number of tokens to generate
1 <= x <= 2048512
Controls output creativity — higher values produce more varied responses
0 <= x <= 20.7
Nucleus sampling probability cutoff
0 <= x <= 10.9
Enable sampling (set true when using temperature or top_p)
false
Response
Music analysis completed successfully
Request status
success Preset used for analysis, when applicable
"catalog_metadata"
Model output for single-preset or custom-prompt analysis. May be plain text or structured JSON depending on the preset.
Full report payload returned only when using the full_report preset
Inference time in seconds
Was this page helpful?
