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

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