API REFERENCE
Analyze Songs
On this page
/api/songs/analyzeAnalyze music using a state-of-the-art Audio Language Model (Music Flamingo) that listens directly to the audio waveform.
Authentication
x-api-key in header
bearerAuth bearer
Request
curl --request POST \
--url 'https://api.recoupable.dev/api/songs/analyze' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"audio_url": "https://example.com/song.mp3"
}'Request body required
Music analysis request
application/json
presetstring · enumName 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.
Values: "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"
promptstringText prompt or question about the music
minLength: 1 · maxLength: 24000
audio_urlstringrequiredPublic 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.
format: uri
max_new_tokensintegerMaximum number of tokens to generate
Default: 512
minimum: 1 · maximum: 2048
temperaturenumberControls output creativity — higher values produce more varied responses
Default: 1
minimum: 0 · maximum: 2
top_pnumberNucleus sampling probability cutoff
Default: 1
minimum: 0 · maximum: 1
do_samplebooleanEnable sampling (set true when using temperature or top_p)
Default: false
Responses
200Music analysis completed successfully+
application/json
statusstring · enumRequest status
Values: "success"
presetstringPreset used for analysis, when applicable
responseanyModel output for single-preset or custom-prompt analysis. May be plain text or structured JSON depending on the preset.
reportobjectFull report payload returned only when using the full_report preset
elapsed_secondsnumberInference time in seconds
format: float
400Bad request — missing or invalid fields, including a missing audio_url (missing_fields: ["audio_url"]) or both preset and prompt in one request+
application/json
statusstring · enumError status
Values: "error"
missing_fieldsarray<string>Path to the first invalid or missing field when validation fails
Item properties for missing_fields
string
errorstringError message describing what went wrong
401Unauthorized — invalid or missing API key / Bearer token+
application/json
statusstring · enumError status
Values: "error"
missing_fieldsarray<string>Path to the first invalid or missing field when validation fails
Item properties for missing_fields
string
errorstringError message describing what went wrong
402Insufficient credits — the balance cannot cover the base price of this request ($0.05 per model call, $0.65 for full_report). The model is not called, nothing is charged, and no Stripe object is created. The body includes a static billingUrl.+
application/json
errorstring · enumrequiredValues: "insufficient_credits"
remaining_creditsintegerrequiredThe account's balance, in credits (micro-dollars: 1,000,000 = $1.00).
required_creditsintegerrequiredThe base price of this request, in credits: 50000 ($0.05) for a single preset or custom prompt, 650000 ($0.65) for full_report. The per-second inference charge is added after the model returns.
billingUrlstringrequiredStatic link to the Recoup app, where a human can save a card and buy credits. It is a constant, not a freshly minted Stripe Checkout Session, so a credit-gated endpoint that keeps returning 402 creates nothing. To buy credits programmatically, call POST /api/credits/sessions.
422Unverifiable audio. Before the model is called, audio_url is checked with a HEAD request (a ranged GET for hosts that reject HEAD). It must answer 2xx within 10 seconds with an audio/* or application/octet-stream content type. When it does not, the model is not called and nothing is charged.+
application/json
statusstring · enumrequiredValues: "error"
errorstring · enumrequiredaudio_url_unreachable: the URL did not answer 2xx within 10 seconds. audio_url_not_audio: it answered, but with a content type that is not audio/* or application/octet-stream.
Values: "audio_url_unreachable", "audio_url_not_audio"
messagestringrequiredWhat the check observed, for the caller's logs.
500Server error — upstream model unavailable or inference failed+
application/json
statusstring · enumError status
Values: "error"
missing_fieldsarray<string>Path to the first invalid or missing field when validation fails
Item properties for missing_fields
string
errorstringError message describing what went wrong
Full specification
Download the OpenAPI file for complete schemas, constraints, and examples.
Download releases.jsonView operation source
{
"description": "Analyze music using a state-of-the-art Audio Language Model ([Music Flamingo](https://www.universalmusic.com/universal-music-group-to-transform-music-experience-for-billions-of-fans-with-nvidia-ai/)) that listens directly to the audio waveform.",
"security": [
{
"apiKeyAuth": []
},
{
"bearerAuth": []
}
],
"requestBody": {
"description": "Music analysis request",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Music analysis completed successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeResponse"
}
}
}
},
"400": {
"description": "Bad request — missing or invalid fields, including a missing `audio_url` (`missing_fields: [\"audio_url\"]`) or both `preset` and `prompt` in one request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeErrorResponse"
}
}
}
},
"401": {
"description": "Unauthorized — invalid or missing API key / Bearer token",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeErrorResponse"
}
}
}
},
"402": {
"description": "Insufficient credits — the balance cannot cover the base price of this request (`$0.05` per model call, `$0.65` for `full_report`). The model is not called, nothing is charged, and no Stripe object is created. The body includes a static `billingUrl`.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeInsufficientCreditsResponse"
}
}
}
},
"422": {
"description": "Unverifiable audio. Before the model is called, `audio_url` is checked with a `HEAD` request (a ranged `GET` for hosts that reject `HEAD`). It must answer 2xx within 10 seconds with an `audio/*` or `application/octet-stream` content type. When it does not, the model is not called and nothing is charged.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeAudioUrlErrorResponse"
}
}
}
},
"500": {
"description": "Server error — upstream model unavailable or inference failed",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongAnalyzeErrorResponse"
}
}
}
}
}
}