{
  "openapi": "3.1.0",
  "info": {
    "title": "TuneLab Audio Intelligence API",
    "version": "v1",
    "description": "TuneLab Audio API \u2014 25+ audio endpoints behind one integration.\n\nStems, analysis, transcription, mastering. Built for media SaaS and\ncreator-tool teams who'd rather ship product than wire up five audio vendors.\n\nOpen models, production-hardened: HTDemucs FT for 4-stem, BS-RoFormer for\nvocals, madmom for beat grids, MAEST for mood features.\n",
    "contact": {
      "name": "TuneLab",
      "url": "https://developers.tunelab.dev",
      "email": "hello@tunelab.dev"
    }
  },
  "servers": [
    {
      "url": "https://api.tunelab.dev",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key (tl_live_* or tl_test_*)"
      }
    },
    "schemas": {
      "MetaEnvelope": {
        "type": "object",
        "properties": {
          "cache": {
            "type": "string",
            "enum": [
              "hit",
              "miss",
              "bypass"
            ],
            "description": "Whether the response came from cache"
          },
          "latency_ms": {
            "type": "integer",
            "description": "Processing time in milliseconds"
          },
          "credits_used": {
            "type": "integer"
          },
          "credits_remaining": {
            "type": "integer"
          },
          "trace_id": {
            "type": "string"
          }
        }
      },
      "Features": {
        "type": "object",
        "properties": {
          "artist": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "tempo": {
            "type": "number",
            "format": "float",
            "description": "BPM, float precision (e.g. 116.01)"
          },
          "key": {
            "type": "string",
            "description": "Musical key (C, C#, D, ..., B)"
          },
          "mode": {
            "type": "string",
            "enum": [
              "major",
              "minor"
            ]
          },
          "camelot": {
            "type": "string",
            "description": "Camelot wheel notation (e.g. \"10A\")"
          },
          "energy": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "danceability": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "happiness": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "acousticness": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "instrumentalness": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "_meta": {
            "$ref": "#/components/schemas/MetaEnvelope"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine-readable error code"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "trace_id": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/analyze": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Analyze by metadata",
        "description": "Returns full audio features for a track identified by song + artist.\nCache hits are free; misses trigger on-demand compute and charge credits.\n",
        "parameters": [
          {
            "name": "song",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "Get Lucky"
          },
          {
            "name": "artist",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "Daft Punk"
          }
        ],
        "responses": {
          "200": {
            "description": "Features returned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Features"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits"
          },
          "404": {
            "description": "Track not found"
          }
        }
      }
    },
    "/v1/key-bpm": {
      "get": {
        "tags": [
          "Analysis"
        ],
        "summary": "Fast BPM + key lookup",
        "description": "Lightweight endpoint that returns only tempo, key, mode, and camelot.\nUses the same cache as /v1/analyze but skips mood features.\n",
        "parameters": [
          {
            "name": "song",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "Get Lucky"
          },
          {
            "name": "artist",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "Daft Punk"
          }
        ],
        "responses": {
          "200": {
            "description": "BPM + key returned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tempo": {
                      "type": "number"
                    },
                    "key": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "string"
                    },
                    "camelot": {
                      "type": "string"
                    },
                    "_meta": {
                      "$ref": "#/components/schemas/MetaEnvelope"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/resolve/{id}": {
      "get": {
        "tags": [
          "Resolution"
        ],
        "summary": "Cross-platform ID resolution",
        "description": "Convert any track ID (Spotify, Apple, Deezer, ISRC, MusicBrainz) into\nall other platform IDs plus identity metadata. Zero-credit operation.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "spotify:2WfaOiMkCvy7F5fcp2zZ8L"
          }
        ],
        "responses": {
          "200": {
            "description": "Identity resolved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mbid": {
                      "type": "string"
                    },
                    "isrc": {
                      "type": "string"
                    },
                    "spotify_id": {
                      "type": "string"
                    },
                    "apple_id": {
                      "type": "string"
                    },
                    "deezer_id": {
                      "type": "string"
                    },
                    "youtube_id": {
                      "type": "string"
                    },
                    "artist": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "_meta": {
                      "$ref": "#/components/schemas/MetaEnvelope"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "ID not recognized"
          }
        }
      }
    },
    "/v1/beatgrid/{id}": {
      "get": {
        "tags": [
          "DJ Intelligence"
        ],
        "summary": "Beat grid with DJ-verified BPM",
        "description": "Returns frame-level beat and downbeat timestamps plus DJ-verified tempo.\nPerfect for syncing decks or building an auto-cue system.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Beat grid returned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tempo": {
                      "type": "number"
                    },
                    "downbeat": {
                      "type": "number"
                    },
                    "beats": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    "downbeats": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    "_meta": {
                      "$ref": "#/components/schemas/MetaEnvelope"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/bpm": {
      "post": {
        "tags": [
          "Upload"
        ],
        "summary": "BPM detection from uploaded audio",
        "description": "POST audio bytes to detect BPM. Supports MP3, WAV, FLAC, OGG, M4A.\nReturns BPM plus confidence. Charges 2 credits per request.\n",
        "requestBody": {
          "required": true,
          "content": {
            "audio/*": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "BPM detected",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tempo": {
                      "type": "number"
                    },
                    "confidence": {
                      "type": "number"
                    },
                    "_meta": {
                      "$ref": "#/components/schemas/MetaEnvelope"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/compat/spotify/audio-features/{id}": {
      "get": {
        "tags": [
          "Spotify Compatibility"
        ],
        "summary": "Spotify Audio Features drop-in",
        "description": "Spotify-compat shim for migrators. Returns audio features in the exact\nJSON shape Spotify's deprecated /v1/audio-features/{id} endpoint used to\nreturn \u2014 zero-code-change switch for teams moving off Spotify. Pass any\nSpotify track ID and receive real DSP features in the original format.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "2WfaOiMkCvy7F5fcp2zZ8L"
          }
        ],
        "responses": {
          "200": {
            "description": "Spotify-shaped features",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "tempo": {
                      "type": "number"
                    },
                    "key": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 11
                    },
                    "mode": {
                      "type": "integer",
                      "enum": [
                        0,
                        1
                      ]
                    },
                    "loudness": {
                      "type": "number"
                    },
                    "energy": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "danceability": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "valence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "acousticness": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "instrumentalness": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "speechiness": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "time_signature": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/identify": {
      "post": {
        "tags": [
          "Track Identification"
        ],
        "summary": "Identify a track from audio",
        "description": "Upload audio to identify the track via a multi-provider fingerprinting cascade.\nReturns artist, title, ISRC, and \u2014 if matched \u2014 free enrichment including BPM, key,\ngenre, streaming platform IDs, and artwork. Synchronous; typical response 3-10 seconds.\nCharges 3 credits per request (cache hits are free).\n",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Audio file (any ffmpeg-supported format \u2014 MP3, WAV, FLAC, OGG, M4A, etc.)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identification complete (matched or unmatched)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "matched",
                    "services_tried",
                    "_meta"
                  ],
                  "properties": {
                    "matched": {
                      "type": "boolean",
                      "description": "Whether the track was identified"
                    },
                    "artist": {
                      "type": "string",
                      "description": "Artist name (present when matched)"
                    },
                    "title": {
                      "type": "string",
                      "description": "Track title (present when matched)"
                    },
                    "album": {
                      "type": "string"
                    },
                    "year": {
                      "type": "string"
                    },
                    "isrc": {
                      "type": "string",
                      "description": "International Standard Recording Code"
                    },
                    "confidence": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100,
                      "description": "Match confidence (0-100)"
                    },
                    "source_service": {
                      "type": "string",
                      "description": "Which cascade service produced the match"
                    },
                    "services_tried": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string",
                        "enum": [
                          "match",
                          "no_match",
                          "error",
                          "skipped"
                        ]
                      },
                      "description": "Status of each identification service attempted"
                    },
                    "enrichment": {
                      "type": "object",
                      "nullable": true,
                      "description": "Free enrichment data from TuneLab's database (null when unmatched)",
                      "properties": {
                        "bpm": {
                          "type": "number"
                        },
                        "key": {
                          "type": "string"
                        },
                        "camelot": {
                          "type": "string"
                        },
                        "genre": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "styles": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "label": {
                          "type": "string"
                        },
                        "spotify_id": {
                          "type": "string"
                        },
                        "apple_id": {
                          "type": "string"
                        },
                        "deezer_id": {
                          "type": "string"
                        },
                        "youtube_id": {
                          "type": "string"
                        },
                        "artwork_url": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    },
                    "_meta": {
                      "$ref": "#/components/schemas/MetaEnvelope"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request (missing file, invalid audio, or audio under 3 seconds)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits"
          },
          "413": {
            "description": "File exceeds tier upload limit (15 MB BASIC / 50 MB PRO)"
          },
          "429": {
            "description": "Rate limit exceeded"
          },
          "502": {
            "description": "All identification services unavailable"
          },
          "503": {
            "description": "Server overloaded \u2014 retry after backoff"
          }
        }
      }
    }
  }
}