RecoupGet a free auditFree audit

API REFERENCE

Analyze Songs

On this page
POST/api/songs/analyze

Analyze 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
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"
}'

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request POST \
  --url 'https://recoup-api.vercel.app/api/songs/analyze' \
  --header 'Content-Type: application/json' \
  --data '{
  "audio_url": "https://example.com/song.mp3"
}'

Request body required

Music analysis request

application/json

presetstring · enum

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.

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"

promptstring

Text prompt or question about the music

minLength: 1 · maxLength: 24000

audio_urlstringrequired

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.

format: uri

max_new_tokensinteger

Maximum number of tokens to generate

Default: 512

minimum: 1 · maximum: 2048

temperaturenumber

Controls output creativity — higher values produce more varied responses

Default: 1

minimum: 0 · maximum: 2

top_pnumber

Nucleus sampling probability cutoff

Default: 1

minimum: 0 · maximum: 1

do_sampleboolean

Enable sampling (set true when using temperature or top_p)

Default: false

Responses

200Music analysis completed successfully

application/json

statusstring · enum

Request status

Values: "success"

presetstring

Preset used for analysis, when applicable

responseany

Model output for single-preset or custom-prompt analysis. May be plain text or structured JSON depending on the preset.

reportobject

Full report payload returned only when using the full_report preset

elapsed_secondsnumber

Inference 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 · enum

Error status

Values: "error"

missing_fieldsarray<string>

Path to the first invalid or missing field when validation fails

Item properties for missing_fields

string

errorstring

Error message describing what went wrong

401Unauthorized — invalid or missing API key / Bearer token

application/json

statusstring · enum

Error status

Values: "error"

missing_fieldsarray<string>

Path to the first invalid or missing field when validation fails

Item properties for missing_fields

string

errorstring

Error 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 · enumrequired

Values: "insufficient_credits"

remaining_creditsintegerrequired

The account's balance, in credits (micro-dollars: 1,000,000 = $1.00).

required_creditsintegerrequired

The 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.

billingUrlstringrequired

Static 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 · enumrequired

Values: "error"

errorstring · enumrequired

audio_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"

messagestringrequired

What the check observed, for the caller's logs.

500Server error — upstream model unavailable or inference failed

application/json

statusstring · enum

Error status

Values: "error"

missing_fieldsarray<string>

Path to the first invalid or missing field when validation fails

Item properties for missing_fields

string

errorstring

Error message describing what went wrong

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download releases.json
View operation source
json
{
  "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"
          }
        }
      }
    }
  }
}