curl --request POST \
--url https://api.recoupable.dev/api/songs/analyze \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"audio_url": "https://example.com/song.mp3",
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": false
}
'import requests
url = "https://api.recoupable.dev/api/songs/analyze"
payload = {
"audio_url": "https://example.com/song.mp3",
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"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({
audio_url: 'https://example.com/song.mp3',
preset: 'catalog_metadata',
prompt: 'Describe the genre, tempo, and mood of this track.',
max_new_tokens: 512,
temperature: 0.7,
top_p: 0.9,
do_sample: false
})
};
fetch('https://api.recoupable.dev/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.dev/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([
'audio_url' => 'https://example.com/song.mp3',
'preset' => 'catalog_metadata',
'prompt' => 'Describe the genre, tempo, and mood of this track.',
'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.dev/api/songs/analyze"
payload := strings.NewReader("{\n \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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.dev/api/songs/analyze")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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.dev/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 \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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>"
}{
"error": "insufficient_credits",
"remaining_credits": 0,
"required_credits": 50000,
"billingUrl": "https://app.recoupable.dev"
}{
"status": "error",
"error": "audio_url_not_audio",
"message": "audio_url answered 200 with content type text/html"
}{
"status": "error",
"missing_fields": [
"<string>"
],
"error": "<string>"
}Analyze Songs
Analyze music using a state-of-the-art Audio Language Model (Music Flamingo) that listens directly to the audio waveform.
curl --request POST \
--url https://api.recoupable.dev/api/songs/analyze \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"audio_url": "https://example.com/song.mp3",
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": false
}
'import requests
url = "https://api.recoupable.dev/api/songs/analyze"
payload = {
"audio_url": "https://example.com/song.mp3",
"preset": "catalog_metadata",
"prompt": "Describe the genre, tempo, and mood of this track.",
"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({
audio_url: 'https://example.com/song.mp3',
preset: 'catalog_metadata',
prompt: 'Describe the genre, tempo, and mood of this track.',
max_new_tokens: 512,
temperature: 0.7,
top_p: 0.9,
do_sample: false
})
};
fetch('https://api.recoupable.dev/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.dev/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([
'audio_url' => 'https://example.com/song.mp3',
'preset' => 'catalog_metadata',
'prompt' => 'Describe the genre, tempo, and mood of this track.',
'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.dev/api/songs/analyze"
payload := strings.NewReader("{\n \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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.dev/api/songs/analyze")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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.dev/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 \"audio_url\": \"https://example.com/song.mp3\",\n \"preset\": \"catalog_metadata\",\n \"prompt\": \"Describe the genre, tempo, and mood of this track.\",\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>"
}{
"error": "insufficient_credits",
"remaining_credits": 0,
"required_credits": 50000,
"billingUrl": "https://app.recoupable.dev"
}{
"status": "error",
"error": "audio_url_not_audio",
"message": "audio_url answered 200 with content type text/html"
}{
"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, plus audio_url. Use preset for structured analysis workflows, or prompt for free-form questions about the audio.
Public URL to an audio file (MP3, WAV, or FLAC, up to 20 minutes). Required in every mode, including a custom prompt. Verified before the model is called: the URL must answer a HEAD request (or a ranged GET) with 2xx within 10 seconds and an audio/* or application/octet-stream content type, else the request returns 422 and nothing is charged.
"https://example.com/song.mp3"
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."
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?
