{
  "openapi": "3.1.0",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "paths": {
    "/admin/db-stats": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Db Stats",
        "description": "Return the full admin dashboard payload.\n\n``stale_days`` controls the threshold for the \"stale connected users\"\nlist (default 14). Recomputed on every request \u2014 no caching.",
        "operationId": "admin_db_stats_admin_db_stats_get",
        "parameters": [
          {
            "name": "stale_days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 14,
              "title": "Stale Days"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Db Stats Admin Db Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobbles/invalid": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin List Invalid Scrobbles",
        "description": "List scrobbles with impossible timestamps.\n\nAlways includes per-bucket counts so the SPA's tabs can stay current\nafter a delete without a second request.",
        "operationId": "admin_list_invalid_scrobbles_admin_scrobbles_invalid_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "all",
              "title": "Kind"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin List Invalid Scrobbles Admin Scrobbles Invalid Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobbles/{scrobble_id}": {
      "delete": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Delete Scrobble",
        "operationId": "admin_delete_scrobble_admin_scrobbles__scrobble_id__delete",
        "parameters": [
          {
            "name": "scrobble_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Scrobble Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Delete Scrobble Admin Scrobbles  Scrobble Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobbles/invalid/purge": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Purge Invalid Scrobbles",
        "operationId": "admin_purge_invalid_scrobbles_admin_scrobbles_invalid_purge_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurgePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Purge Invalid Scrobbles Admin Scrobbles Invalid Purge Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/tautulli/events": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Tautulli Events",
        "description": "List received Tautulli events, newest-first, with optional filters.\n\nAlways returns the distinct filter values so the SPA renders its\ndropdowns in one request (same contract as ``/admin/task-history``).",
        "operationId": "admin_tautulli_events_admin_tautulli_events_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Event"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Category"
            }
          },
          {
            "name": "media_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Type"
            }
          },
          {
            "name": "user",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "User"
            }
          },
          {
            "name": "since_days",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Since Days"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Q"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Tautulli Events Admin Tautulli Events Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/tautulli/stats": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Tautulli Stats",
        "description": "Operational stats for the Tautulli-events panel.\n\nAccepts the same filters as the list endpoint so the numbers always\ndescribe the slice the table is showing.",
        "operationId": "admin_tautulli_stats_admin_tautulli_stats_get",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Days"
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Event"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Category"
            }
          },
          {
            "name": "media_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Type"
            }
          },
          {
            "name": "user",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "User"
            }
          },
          {
            "name": "since_days",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Since Days"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Q"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Tautulli Stats Admin Tautulli Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/task-history": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Task History",
        "description": "List recent task runs, newest-first, with optional filters.\n\nAlways returns ``names`` (every distinct task name seen) and\n``counts_by_status`` so the SPA can render its filter dropdown +\nstatus badges in one request.",
        "operationId": "admin_task_history_admin_task_history_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Task History Admin Task History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/task-history/running": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Task History Running",
        "description": "The currently-running task for a backfill family, or ``null``.\n\nThe Backfills page calls this per card on mount (passing the card's\ntask-name prefix) so a page reload re-binds to an in-flight task \u2014\nshowing live progress + a Stop button instead of a fresh, runnable\ncard that would let you start a duplicate.",
        "operationId": "admin_task_history_running_admin_task_history_running_get",
        "parameters": [
          {
            "name": "name_prefix",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name Prefix"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Task History Running Admin Task History Running Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/task-history/{task_id}": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Task History Detail",
        "operationId": "admin_task_history_detail_admin_task_history__task_id__get",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Task History Detail Admin Task History  Task Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/task-history/{task_id}/cancel": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Task History Cancel",
        "description": "Request cooperative cancellation of a running background task.\n\nSets an in-process flag the task's loop checks each iteration; the\ntask stops at its next checkpoint and is recorded as ``cancelled``\n(not ``failed``). Returns 404 if the task doesn't exist. A no-op\n(``was_running: false``) if the task already finished \u2014 the SPA treats\nthat as \"already done\" and just refreshes.",
        "operationId": "admin_task_history_cancel_admin_task_history__task_id__cancel_post",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Task History Cancel Admin Task History  Task Id  Cancel Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/spotify/audio-features-cron-status": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Spotify Audio Features Cron Status",
        "description": "Recent runs + a \"looks deprecated\" heuristic for the\n``spotify_audio_features_backfill`` cron.\n\nSpotify deprecated ``/v1/audio-features`` in November 2024. Apps\nwithout an exemption get 403 on every call; the cron silently\nrecords ``status: \"fetch_failed\"`` in task_history and exits.\nThis endpoint surfaces the pattern so admins can decide whether\nto lower the cron's cadence or disable it. See\n:mod:`api.admin.spotify_status` for the heuristic.",
        "operationId": "admin_spotify_audio_features_cron_status_admin_spotify_audio_features_cron_status_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Spotify Audio Features Cron Status Admin Spotify Audio Features Cron Status Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/acousticbrainz/status": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Acousticbrainz Status",
        "description": "Coverage counts for the AcousticBrainz feature backfill.\n\nReturns how many MBIDs we've looked up (positive + negative) plus\nhow many MusicBrainz-linked canonical tracks still have no AB\nlookup \u2014 i.e. the backfill's remaining work.",
        "operationId": "admin_acousticbrainz_status_admin_acousticbrainz_status_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Acousticbrainz Status Admin Acousticbrainz Status Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/acousticbrainz/backfill": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Acousticbrainz Backfill",
        "description": "Kick off one AcousticBrainz backfill batch as a background task.\n\nFire-and-forget \u2014 returns a ``task_id`` the SPA polls. Walks\nMusicBrainz-linked canonical tracks with no AB lookup yet, fetches\neach from the (maintenance-mode, CC0) AcousticBrainz API, caches\nthe result, and re-merges the canonical so ``ab_features`` lands.\n\nManual-trigger only \u2014 there is intentionally no cron. The AB\nservice is a free single-author host; we don't impose background\nload on it. Re-click to process the next batch.",
        "operationId": "admin_acousticbrainz_backfill_admin_acousticbrainz_backfill_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 250,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Acousticbrainz Backfill Admin Acousticbrainz Backfill Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/radio/discovery-albums/coverage": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Discovery Album Coverage",
        "description": "Coverage for the Discover-page album backfill.\n\nReturns how many track recommendations have an album label and how\nmany still need one \u2014 i.e. the backfill's remaining work.",
        "operationId": "admin_discovery_album_coverage_admin_radio_discovery_albums_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discovery Album Coverage Admin Radio Discovery Albums Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/radio/discovery-albums/backfill": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Discovery Album Backfill",
        "description": "Backfill ``album_title``/``album_id`` on existing discovery rows.\n\nFire-and-forget background task. ``not_playable`` rows fill free from\nthe canonical track's album; ``not_in_library`` tracks resolve the\nalbum via a cached, paced LastFM ``track.getInfo`` lookup (each track\nis looked up at most once). ``limit`` bounds rows scanned per run \u2014\nre-click to process the next batch.",
        "operationId": "admin_discovery_album_backfill_admin_radio_discovery_albums_backfill_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discovery Album Backfill Admin Radio Discovery Albums Backfill Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/ask": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Ask",
        "description": "Ask the assistant a question; append both turns to a conversation.\n\nCreates a conversation when ``conversation_id`` is absent. Always 200\nwith a ``state`` (``ok`` / ``not_configured`` / ``failed``) so the SPA\ncan degrade instead of erroring. A failed answer is not persisted \u2014\nthe user's question stays in the box to retry.",
        "operationId": "admin_ask_admin_ask_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Ask Admin Ask Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/ask/conversations": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Ask Conversations",
        "description": "This admin's recent threads, newest first (no message bodies).",
        "operationId": "admin_ask_conversations_admin_ask_conversations_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Ask Conversations Admin Ask Conversations Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/ask/conversations/{conversation_id}": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Ask Conversation",
        "operationId": "admin_ask_conversation_admin_ask_conversations__conversation_id__get",
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Conversation Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Ask Conversation Admin Ask Conversations  Conversation Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Delete Ask Conversation",
        "operationId": "admin_delete_ask_conversation_admin_ask_conversations__conversation_id__delete",
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Conversation Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Delete Ask Conversation Admin Ask Conversations  Conversation Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/ask/wishlist": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Admin Ask Wishlist",
        "description": "Wishlist a suggestion the assistant surfaced.\n\nResolves **by exact external identifier only** \u2014 never by name. A\nsuggestion reaches here already confirmed in Deezer or MusicBrainz,\nand seeding the canonical from that id is the same no-name-guessing\npath the search fallback's click-through uses, so discovery can't\nintroduce a mislink. Seeds the canonical when we don't have it yet.",
        "operationId": "admin_ask_wishlist_admin_ask_wishlist_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskWishlistPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Ask Wishlist Admin Ask Wishlist Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Login",
        "description": "Verify credentials, set the session cookie, return the user.\n\nGeneric 401 on any failure \u2014 never leak whether the username exists.",
        "operationId": "login_auth_login_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Login Auth Login Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/register": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Register",
        "description": "Self-serve signup. Creates a ``viewer`` and auto-logs in.\n\nAdmins are still admin-created via ``POST /auth/users/`` \u2014\nself-registration intentionally has no role field on the wire.",
        "operationId": "register_auth_register_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Register Auth Register Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Logout",
        "operationId": "logout_auth_logout_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Logout Auth Logout Post"
                }
              }
            }
          }
        }
      }
    },
    "/auth/me": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Me",
        "operationId": "me_auth_me_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Auth Me Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "auth"
        ],
        "summary": "Update Me",
        "description": "Patch the current user's preferences (shallow-merged).",
        "operationId": "update_me_auth_me_patch",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreferencesPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update Me Auth Me Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/me/password": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Change Password",
        "operationId": "change_password_auth_me_password_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordChangePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Change Password Auth Me Password Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "List Users",
        "operationId": "list_users_auth_users__get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Users Auth Users  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Create User",
        "operationId": "create_user_auth_users__post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Create User Auth Users  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/{username}": {
      "patch": {
        "tags": [
          "auth"
        ],
        "summary": "Update User",
        "operationId": "update_user_auth_users__username__patch",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update User Auth Users  Username  Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "auth"
        ],
        "summary": "Delete User",
        "operationId": "delete_user_auth_users__username__delete",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete User Auth Users  Username  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/{username}/password": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Admin Reset Password",
        "operationId": "admin_reset_password_auth_users__username__password_post",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminPasswordResetPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Reset Password Auth Users  Username  Password Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/search": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Search Artists",
        "operationId": "search_artists_artists_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Search Artists Artists Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/search": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Search Albums",
        "operationId": "search_albums_albums_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Search Albums Albums Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/search": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Search Tracks",
        "operationId": "search_tracks_tracks_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Search Tracks Tracks Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/resolve": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Resolve Album Endpoint",
        "description": "Resolve any source identifier(s) to the canonical album.\n\nWhen ``deezer=N`` is supplied and no canonical exists yet, the\nendpoint **seeds** the canonical by fetching + caching the Deezer\nalbum (which triggers the eager canonical reconcile via the catalog\nupsert hook), then re-resolves and returns. This makes click-through\nfrom Deezer-fallback search results a single HTTP call \u2014 no\n\"ensure-then-resolve\" dance on the client.\n\n``lastfm=<artist::title>`` works the same way: we fetch via the\nLastFM dedup layer (which writes the cache + triggers the\ncanonical reconcile), then re-resolve. Used by the artist-\ndiscography import flow for LastFM-only fallback rows.\n\nReturns the canonical doc + every known external ref. 404 if we\ncan't resolve from any provided signal (e.g. unknown MBID with no\nDeezer ID to seed from).",
        "operationId": "resolve_album_endpoint_albums_resolve_get",
        "parameters": [
          {
            "name": "deezer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Deezer"
            }
          },
          {
            "name": "mbid",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Mbid"
            }
          },
          {
            "name": "upc",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Upc"
            }
          },
          {
            "name": "plex_server",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Server"
            }
          },
          {
            "name": "plex_rating_key",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Rating Key"
            }
          },
          {
            "name": "lastfm",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Lastfm"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Resolve Album Endpoint Albums Resolve Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/{album_id}": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Album",
        "operationId": "get_album_albums__album_id__get",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Album Albums  Album Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/{album_id}/tracks": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Album Tracks",
        "description": "Canonical tracklist for an album \u2014 source-agnostic.\n\nReturns the album's tracks straight from the canonical ``media_tracks``\ncollection (keyed by ``album_id``), so an album gets a tracklist\nwhatever source minted those tracks \u2014 Plex, MusicBrainz, Spotify,\niTunes or Deezer \u2014 rather than only when a live Deezer fetch is\navailable. Ordered by disc then track number (nulls last).\n\nFollows the album's ``merged_into`` chain and excludes merged-away\ntracks. Each row carries what the SPA needs to render + route\nplayback: ``sources`` (Plex-playability gate) and ``preview_url`` /\n``deezer_id`` for the 30s-preview fallback.",
        "operationId": "get_album_tracks_albums__album_id__tracks_get",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Get Album Tracks Albums  Album Id  Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/resolve": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Resolve Artist Endpoint",
        "description": "Resolve-or-seed. See ``resolve_album_endpoint`` for the pattern.\n\n``lastfm=<lowercased_name>`` mints a LastFM-only canonical when no\nother source has the artist (used by the related-artist import\nflow). Composite shape NOT applicable for artists \u2014 just the\nlowercased name (see :func:`resolver.lastfm_artist_id`).",
        "operationId": "resolve_artist_endpoint_artists_resolve_get",
        "parameters": [
          {
            "name": "deezer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Deezer"
            }
          },
          {
            "name": "mbid",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Mbid"
            }
          },
          {
            "name": "plex_server",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Server"
            }
          },
          {
            "name": "plex_rating_key",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Rating Key"
            }
          },
          {
            "name": "lastfm",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Lastfm"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Resolve Artist Endpoint Artists Resolve Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/{artist_id}": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Artist",
        "operationId": "get_artist_artists__artist_id__get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Artist Artists  Artist Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/{artist_id}/discography": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Artist Discography",
        "description": "Grouped + classified discography for an artist.\n\nCanonical albums first (full ``sources`` bitmap, ``primary_type`` +\n``secondary_types`` carried through). Augmented with MusicBrainz\nrelease-groups, Deezer artist albums, and Last.fm top-albums that\naren't yet in the canonical layer \u2014 each surfaced as a fallback\ncard with a ``+ Import`` affordance on the SPA.\n\nFive buckets: Studio / Live / Compilations / EPs & Singles /\nOther. Year-descending within each. See\n:mod:`api.canonical.discography` for the pipeline.",
        "operationId": "get_artist_discography_artists__artist_id__discography_get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Artist Discography Artists  Artist Id  Discography Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/{artist_id}/related": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Artist Related",
        "description": "Related artists (Deezer + LastFM, deduped) + MB affiliations.\n\n``sort`` \u2208 ``{relevance, alpha}`` \u2014 default ranks multi-source +\nhigh-match first; alpha is straight alphabetical. ``in_library_only``\ndrops fallback rows so the user can see only canonicals.\n\nAffiliations are MB structural relationships (member-of, subgroup,\nfounder, collaborator, tribute, family) \u2014 always returned, never\nfiltered, since they're factual rather than fuzzy.\n\nSee :mod:`api.canonical.related` for the pipeline.",
        "operationId": "get_artist_related_artists__artist_id__related_get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "relevance",
              "title": "Sort"
            }
          },
          {
            "name": "in_library_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "In Library Only"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Artist Related Artists  Artist Id  Related Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/resolve": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Resolve Track Endpoint",
        "description": "Resolve-or-seed. See ``resolve_album_endpoint`` for the pattern.",
        "operationId": "resolve_track_endpoint_tracks_resolve_get",
        "parameters": [
          {
            "name": "deezer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Deezer"
            }
          },
          {
            "name": "mbid",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Mbid"
            }
          },
          {
            "name": "isrc",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Isrc"
            }
          },
          {
            "name": "plex_server",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Server"
            }
          },
          {
            "name": "plex_rating_key",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Plex Rating Key"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Resolve Track Endpoint Tracks Resolve Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/{track_id}": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Track",
        "operationId": "get_track_tracks__track_id__get",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Track Tracks  Track Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/{track_id}/lyrics": {
      "get": {
        "tags": [
          "canonical"
        ],
        "summary": "Get Track Lyrics",
        "description": "Lyrics for a canonical track (plain + parsed synced lines).\n\nReads the ``lyrics_cache``. On a cache miss (or a stale negative\nhit), ``enrich=true`` does a one-off on-demand fetch (Plex harvest \u2192\nLRCLIB) so opening a never-seen track Just Works; the bulk drain\nhandles coverage at scale. Returns a ``not_found`` envelope rather\nthan 404 when there genuinely are no lyrics, so the SPA can render an\nempty state without treating it as an error.",
        "operationId": "get_track_lyrics_tracks__track_id__lyrics_get",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track Id"
            }
          },
          {
            "name": "enrich",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Enrich"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Track Lyrics Tracks  Track Id  Lyrics Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/{album_id}/refs": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Link Album Source",
        "operationId": "link_album_source_albums__album_id__refs_post",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkSourcePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Link Album Source Albums  Album Id  Refs Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/{album_id}/refs/{source}/{external_id}": {
      "delete": {
        "tags": [
          "canonical"
        ],
        "summary": "Unlink Album Source",
        "operationId": "unlink_album_source_albums__album_id__refs__source___external_id__delete",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album Id"
            }
          },
          {
            "name": "source",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Source"
            }
          },
          {
            "name": "external_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "External Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unlink Album Source Albums  Album Id  Refs  Source   External Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/{artist_id}/refs": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Link Artist Source",
        "operationId": "link_artist_source_artists__artist_id__refs_post",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkSourcePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Link Artist Source Artists  Artist Id  Refs Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/{artist_id}/refs/{source}/{external_id}": {
      "delete": {
        "tags": [
          "canonical"
        ],
        "summary": "Unlink Artist Source",
        "operationId": "unlink_artist_source_artists__artist_id__refs__source___external_id__delete",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "source",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Source"
            }
          },
          {
            "name": "external_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "External Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unlink Artist Source Artists  Artist Id  Refs  Source   External Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/{track_id}/refs": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Link Track Source",
        "operationId": "link_track_source_tracks__track_id__refs_post",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkSourcePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Link Track Source Tracks  Track Id  Refs Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/{track_id}/refs/{source}/{external_id}": {
      "delete": {
        "tags": [
          "canonical"
        ],
        "summary": "Unlink Track Source",
        "operationId": "unlink_track_source_tracks__track_id__refs__source___external_id__delete",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track Id"
            }
          },
          {
            "name": "source",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Source"
            }
          },
          {
            "name": "external_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "External Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unlink Track Source Tracks  Track Id  Refs  Source   External Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/albums/refs/check": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Check Album Refs",
        "operationId": "check_album_refs_albums_refs_check_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefsCheckPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "title": "Response Check Album Refs Albums Refs Check Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/artists/refs/check": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Check Artist Refs",
        "operationId": "check_artist_refs_artists_refs_check_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefsCheckPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "title": "Response Check Artist Refs Artists Refs Check Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tracks/refs/check": {
      "post": {
        "tags": [
          "canonical"
        ],
        "summary": "Check Track Refs",
        "operationId": "check_track_refs_tracks_refs_check_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefsCheckPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "title": "Response Check Track Refs Tracks Refs Check Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/duplicates": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Canonical Duplicates",
        "description": "Library-wide duplicate-canonical groups for cleanup.\n\nAggregates ``media_artists`` (or ``media_albums`` / ``media_tracks``)\nby the dedup key \u2014 ``name_folded`` for artists, ``(artist_id,\ntitle_folded)`` for albums/tracks (artist-scoped so \"Greatest Hits\"\nby different artists doesn't collapse). Returns groups with \u22652\nnon-tombstoned candidates, ordered by candidate-count desc so the\nworst offenders surface first.\n\nEach candidate carries the data the SPA needs to render a row\n(picture/cover, source_count, sources bitmap, year). Pagination\nis via ``page`` + ``limit``; ``has_more`` indicates whether\nmore pages exist.\n\n``q`` is an optional substring filter applied BEFORE the\n``$group`` stage so it searches the whole collection \u2014 not just\nthe current page. For artists it matches ``name_folded``; for\nalbums/tracks it matches ``title_folded`` OR the raw\n``artist_name`` (case-insensitive) so the user can find duplicates\nby either title or performer.\n\nNo scrobble-count enrichment in v1 \u2014 would require a per-\ncandidate $lookup which dominates query time for canonicals with\nmany scrobbles. Can add later as a separate enrichment endpoint\ncalled only when the user expands a group.",
        "operationId": "admin_canonical_duplicates_admin_canonical_duplicates_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Q"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Canonical Duplicates Admin Canonical Duplicates Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/albums/{target_id}/merge": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Merge Albums",
        "operationId": "admin_merge_albums_admin_canonical_albums__target_id__merge_post",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Merge Albums Admin Canonical Albums  Target Id  Merge Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/artists/{target_id}/merge": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Merge Artists",
        "operationId": "admin_merge_artists_admin_canonical_artists__target_id__merge_post",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Merge Artists Admin Canonical Artists  Target Id  Merge Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/tracks/{target_id}/merge": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Merge Tracks",
        "operationId": "admin_merge_tracks_admin_canonical_tracks__target_id__merge_post",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Merge Tracks Admin Canonical Tracks  Target Id  Merge Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/migrate": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Run Migration",
        "description": "Full one-shot migration: backfill canonical + re-key user data.\n\nUse after deploying the canonical layer onto an environment with\nexisting legacy user-data rows (those still carrying ``deezer_id``\ninstead of ``canonical_id``). Idempotent \u2014 safe to re-run; the\nbackfill phase just refreshes already-canonicalized entities.\n\nFire-and-forget: full migrations walk every source-cache entity\n(typically thousands of docs) so they routinely take minutes.\nThe SPA polls ``/admin/task-history/{task_id}`` for progress.\n\nSafety: source caches (``lastfm_scrobbles``, ``plex_*``,\n``deezer_*``, ``musicbrainz_*``) are read-only during the entire\nrun. The only deletions are unresolvable rows in the user-action\ncollections (``media_album_status`` + ``media_favorites``). See\n:mod:`api.canonical.migrate` for the full safety contract.",
        "operationId": "admin_run_migration_admin_canonical_migrate_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Run Migration Admin Canonical Migrate Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/rebuild": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Run Rebuild",
        "description": "Backfill-only: recompute every canonical doc from current sources.\n\nUse after editing the priority tables or projector functions when\nthe existing canonical entities' merged shape needs to catch up.\nDoesn't touch user-data (wishlist / owned / favorites) \u2014 those\nalready point at canonical IDs. Much cheaper than ``/migrate`` when\nyou only need to refresh the projection.\n\nFire-and-forget \u2014 see ``admin_run_migration`` for the rationale.\n\nSafety: source caches are read-only; nothing is ever deleted. This\nendpoint only writes to ``media_*`` and ``*_external_refs``.",
        "operationId": "admin_run_rebuild_admin_canonical_rebuild_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Run Rebuild Admin Canonical Rebuild Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/stats": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Canonical Stats",
        "description": "Health view of the canonical layer.\n\nReturns counts per canonical collection, total external refs, plus\na breakdown of refs by source (so admins can see \"we know about N\nDeezer albums but only M MusicBrainz release-groups\"). Cheap reads\nonly \u2014 runs on every Migrations panel render.",
        "operationId": "admin_canonical_stats_admin_canonical_stats_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Canonical Stats Admin Canonical Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/mb-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Mb Coverage",
        "description": "Per-kind MusicBrainz coverage: total canonicals, how many have an\nMBID available to hydrate from, how many are already MB-cached.\n\nThe gap (with_mb_ref \u2212 mb_entities_cached) is the hydration backlog\n\"Hydrate all\" drains.\n\n``mb_coverage`` is synchronous PyMongo (a few bulk reads + an\nin-memory join). We offload it to a worker thread so it never blocks\nthe event loop \u2014 otherwise this admin page, which fires\n``/musicbrainz/admin/health`` and this endpoint together, would stall\nthe sibling request behind it (the cause of the earlier 15s timeout).",
        "operationId": "admin_mb_coverage_admin_canonical_enrich_mb_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Mb Coverage Admin Canonical Enrich Mb Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/hydrate-mb": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Hydrate Mb",
        "description": "Kick off MB hydration for ``kind`` as a background task.\n\nFetches the MusicBrainz entity for every canonical that carries an\nMB ref (e.g. stamped from a Plex ``mbid://`` Guid) but has no cached\nMB data yet. Each fetch caches the entity and fires the existing\nreconcile, so the canonical re-merges with real MB metadata.\n\n``drain=False`` (default): one ``limit``-sized batch (capped 1000) \u2014\na quick top-up. ``drain=True``: the \"hydrate all\" path \u2014 a single\ntask that walks the *entire* backlog (bounded by\n``HYDRATE_DRAIN_CAP``) so the user doesn't have to click repeatedly.\n\nMusicBrainz-throttled (1 rps); offloaded to a background task and\npolled via ``/admin/task-history/{task_id}``. Re-run to continue;\nalready-hydrated refs are skipped.",
        "operationId": "admin_hydrate_mb_admin_canonical_enrich_hydrate_mb_post",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "track",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Hydrate Mb Admin Canonical Enrich Hydrate Mb Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/promote-lastfm-mbids": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Promote Lastfm Mbids",
        "description": "Promote LastFM-held MBIDs to MusicBrainz refs for ``kind``.\n\nFor canonicals minted from LastFM that carry an MBID in their\nLastFM cache doc but no MusicBrainz ref, stamp the MB ref onto the\nexisting canonical (conflict-guarded \u2014 skips MBIDs already owned by\nanother canonical) and fetch the entity, so the canonical re-merges\nwith real MB data.\n\nOnly ``artist`` and ``track`` are eligible \u2014 LastFM album MBIDs are\nrelease-vs-release-group-ambiguous and are handled in the discovery\nphase instead.\n\nMusicBrainz-throttled background task; poll\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_promote_lastfm_mbids_admin_canonical_enrich_promote_lastfm_mbids_post",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "track",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Promote Lastfm Mbids Admin Canonical Enrich Promote Lastfm Mbids Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/deezer-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Deezer Coverage",
        "description": "Per-kind canonical-out Deezer coverage: total canonicals, how many\nare Deezer-linked, how many are discoverable now (have an ISRC / UPC,\nor \u2014 for artists \u2014 a Deezer-linked sibling).\n\nSynchronous PyMongo offloaded to a worker thread so it never blocks\nthe event loop (see ``admin_mb_coverage``).",
        "operationId": "admin_deezer_coverage_admin_canonical_enrich_deezer_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Deezer Coverage Admin Canonical Enrich Deezer Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/discover-deezer": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Discover Deezer",
        "description": "Attach Deezer entities to canonicals by exact identifier.\n\nTracks match on ISRC, albums on UPC, artists cascade off a\nDeezer-linked sibling \u2014 each stamped onto the existing canonical\n(conflict-guarded), no name guessing. ``drain=True`` walks the whole\nbacklog in one task. Deezer-paced background task; poll\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_discover_deezer_admin_canonical_enrich_discover_deezer_post",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "track",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discover Deezer Admin Canonical Enrich Discover Deezer Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/itunes-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Itunes Coverage",
        "description": "Per-kind canonical-out iTunes coverage: total canonicals, how many\nare iTunes-linked, how many are discoverable now (album has a UPC,\ntrack's album is iTunes-linked, or artist has an iTunes-linked sibling).\n\nSynchronous PyMongo offloaded to a worker thread so it never blocks\nthe event loop (see ``admin_mb_coverage``).",
        "operationId": "admin_itunes_coverage_admin_canonical_enrich_itunes_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Itunes Coverage Admin Canonical Enrich Itunes Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/discover-itunes": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Discover Itunes",
        "description": "Attach iTunes entities to canonicals.\n\nAlbums match on UPC (exact barcode), artists cascade off an\niTunes-linked sibling, tracks match album-position-wise within an\nalready-linked album \u2014 each stamped onto the existing canonical\n(conflict-guarded). ``drain=True`` walks the whole backlog in one\ntask. iTunes-paced (~3s/candidate, 20 req/min cap); poll\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_discover_itunes_admin_canonical_enrich_discover_itunes_post",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "album",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discover Itunes Admin Canonical Enrich Discover Itunes Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/album-track-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Album Track Coverage",
        "description": "Per-source linkable backlog for album-anchored track linking: how\nmany albums carry the source ref, how many of those have unlinked\ntracks, and the unlinked-track upper bound a \"Link all\" run targets.\n\nSynchronous PyMongo offloaded to a worker thread (see\n``admin_mb_coverage``).",
        "operationId": "admin_album_track_coverage_admin_canonical_enrich_album_track_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Album Track Coverage Admin Canonical Enrich Album Track Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/link-album-tracks": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Link Album Tracks",
        "description": "Link an album's unlinked tracks to Deezer / MusicBrainz by matching\nthe source's tracklist to ours by ``(disc, track)`` position.\n\nEdition-gated: a whole album is skipped unless its source tracklist\nhas matching track + disc counts and aligned titles \u2014 so partial /\nwrong-edition mislinks don't happen. Harvests ISRCs as a side effect\n(the matched track's full entity is fetched + re-merged).\n``title_fallback=True`` additionally links, *inside* albums the\nedition gate rejects, tracks whose title is unique on both sides \u2014\nno position and no edition assumption. That is what links a local\n27-track rip against a 25-track streaming edition, which the gate\nalone can never do. Off by default: it is looser evidence, and the\nsummary counts it separately (``title_matched``).\n\n``drain=True`` walks the whole backlog. Source-paced background task;\npoll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_link_album_tracks_admin_canonical_enrich_link_album_tracks_post",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "deezer",
              "title": "Source"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "title_fallback",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Title Fallback"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Link Album Tracks Admin Canonical Enrich Link Album Tracks Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/errors": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Errors",
        "description": "Deduped log of individual enrichment calls that failed.\n\nOne row per ``<source>:<kind>:<canonical_id>`` (the repeat-failing\nentity, not a pile of duplicate rows) \u2014 so you can see *which* calls\nare broken, not just an aggregate count. Rows clear themselves when\nthe entity later enriches successfully. ``source`` is the operation\n(``hydrate_mb`` / ``promote_lastfm`` / ``deezer_discover`` /\n``itunes_discover`` / ``isrc_link``). Returns the rows plus a\n``counts`` map (per-source totals) for the section badges.\n\nSynchronous PyMongo offloaded to a worker thread so it never blocks\nthe event loop.",
        "operationId": "admin_enrich_errors_admin_canonical_enrich_errors_get",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Source"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Errors Admin Canonical Enrich Errors Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Clear Enrich Errors",
        "description": "Clear the enrichment error log \u2014 all of it, or one ``source``.",
        "operationId": "admin_clear_enrich_errors_admin_canonical_enrich_errors_delete",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Source"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Clear Enrich Errors Admin Canonical Enrich Errors Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/lyrics-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Lyrics Coverage",
        "description": "Library-wide lyrics coverage: eligible tracks, how many have\nlyrics (and synced), instrumentals, and the not-yet-tried backlog.\n\nSynchronous PyMongo offloaded to a worker thread (see\n``admin_mb_coverage``).",
        "operationId": "admin_lyrics_coverage_admin_canonical_enrich_lyrics_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Lyrics Coverage Admin Canonical Enrich Lyrics Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/lyrics": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Lyrics",
        "description": "Fill the per-track lyrics cache (Plex harvest first, then LRCLIB).\n\n``drain=True`` walks the whole backlog in one task. LRCLIB-paced\nbackground task; poll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_lyrics_admin_canonical_enrich_lyrics_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Lyrics Admin Canonical Enrich Lyrics Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/mb-relations-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Mb Relations Coverage",
        "description": "How many MB-linked canonical artists have had their relations\n(external links + members) fetched vs. the remaining backlog.",
        "operationId": "admin_mb_relations_coverage_admin_canonical_enrich_mb_relations_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Mb Relations Coverage Admin Canonical Enrich Mb Relations Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/mb-relations": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Mb Relations",
        "description": "Backfill MB external links + band membership onto canonical artists.\n\nRe-fetches each MB-linked artist with the relation includes (MB-paced,\n~1 req/s), re-projecting ``external_links`` / ``members`` /\n``member_of``. ``drain=True`` walks the whole backlog in one task.\nPoll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_mb_relations_admin_canonical_enrich_mb_relations_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Mb Relations Admin Canonical Enrich Mb Relations Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/mb-credits-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Mb Credits Coverage",
        "description": "How many MB-linked canonical tracks have had their writer credits\nresolved vs. the remaining backlog.",
        "operationId": "admin_mb_credits_coverage_admin_canonical_enrich_mb_credits_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Mb Credits Coverage Admin Canonical Enrich Mb Credits Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/mb-credits": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Mb Credits",
        "description": "Backfill composer/lyricist/writer credits onto canonical tracks.\n\nWalks recording\u2192work\u2192artist (\u22652 MB requests per track, MB-paced), so\nthis is the heaviest enrich drain. ``drain=True`` walks the whole\nbacklog. Poll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_mb_credits_admin_canonical_enrich_mb_credits_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Mb Credits Admin Canonical Enrich Mb Credits Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/audio-quality-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Audio Quality Coverage",
        "description": "How many Plex-sourced canonical tracks carry an audio_quality\ndescriptor vs. the remaining (un-reprojected) backlog.",
        "operationId": "admin_audio_quality_coverage_admin_canonical_enrich_audio_quality_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Audio Quality Coverage Admin Canonical Enrich Audio Quality Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/audio-quality": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Audio Quality",
        "description": "Re-project local-file audio quality (codec / bit-depth / lossless)\nonto Plex-sourced canonical tracks. No network \u2014 reads the already-\ncached Plex mirror \u2014 so it's fast. ``drain=True`` walks the whole\nbacklog. Poll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_audio_quality_admin_canonical_enrich_audio_quality_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1000,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Audio Quality Admin Canonical Enrich Audio Quality Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/tags-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Tags Coverage",
        "description": "How many canonical tracks + albums carry the unified tags field\nvs. the remaining (un-reprojected) backlog.",
        "operationId": "admin_tags_coverage_admin_canonical_enrich_tags_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Tags Coverage Admin Canonical Enrich Tags Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/tags": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Tags",
        "description": "Re-project the unified tags / moods / styles onto canonical tracks\n+ albums. No network \u2014 combines already-cached Plex / MusicBrainz /\nLastFM / AcousticBrainz data \u2014 so it's fast. ``drain=True`` walks the\nwhole backlog. Poll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_tags_admin_canonical_enrich_tags_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1000,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Tags Admin Canonical Enrich Tags Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/artist-reproject-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Artist Reproject Coverage",
        "description": "How many canonical artists have been re-projected (carry the\n``alt_names`` field) vs. the remaining backlog.",
        "operationId": "admin_artist_reproject_coverage_admin_canonical_enrich_artist_reproject_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Artist Reproject Coverage Admin Canonical Enrich Artist Reproject Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/artist-reproject": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Enrich Artist Reproject",
        "description": "Re-project canonical artists from the already-cached source data \u2014\nmost usefully MusicBrainz alternate names. No network, so fast.\n(External links / band membership still need the paced MB-relations\nbackfill.) ``drain=True`` walks the whole backlog. Poll\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_enrich_artist_reproject_admin_canonical_enrich_artist_reproject_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 2000,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Enrich Artist Reproject Admin Canonical Enrich Artist Reproject Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/discogs-coverage": {
      "get": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Discogs Coverage",
        "description": "Coverage for both Discogs backfills: barcode auto-link (UPC-bearing\nalbums \u2192 Discogs-linked) and re-project (counts of Discogs-linked\nalbums + artists).",
        "operationId": "admin_discogs_coverage_admin_canonical_enrich_discogs_coverage_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discogs Coverage Admin Canonical Enrich Discogs Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/discogs-discover": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Discogs Discover",
        "description": "Barcode auto-link: attach Discogs releases to UPC-bearing albums.\n\nMusicBrainz-style network drain (Discogs paces to ~1 req/s). ``drain``\nwalks the whole backlog. Poll ``/admin/task-history/{task_id}``.",
        "operationId": "admin_discogs_discover_admin_canonical_enrich_discogs_discover_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discogs Discover Admin Canonical Enrich Discogs Discover Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/canonical/enrich/discogs-reproject": {
      "post": {
        "tags": [
          "canonical",
          "admin"
        ],
        "summary": "Admin Discogs Reproject",
        "description": "Re-project Discogs-linked albums + artists from already-cached data.\nNo network \u2014 fast. ``drain`` walks the whole backlog. Poll\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_discogs_reproject_admin_canonical_enrich_discogs_reproject_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1000,
              "title": "Limit"
            }
          },
          {
            "name": "drain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Drain"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Discogs Reproject Admin Canonical Enrich Discogs Reproject Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/artists/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Artists",
        "operationId": "get_artists_deezer_artists__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/deezer/artist/{artist_id}/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Artist",
        "operationId": "get_artist_deezer_artist__artist_id___get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Artist Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/albums/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Albums",
        "operationId": "get_albums_deezer_albums__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/deezer/album/{album_id}/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Album",
        "operationId": "get_album_deezer_album__album_id___get",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Album Id"
            }
          },
          {
            "name": "process",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Process"
            }
          },
          {
            "name": "wanted",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Wanted"
            }
          },
          {
            "name": "downloaded",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Downloaded"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/track/{track_id}/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Track",
        "operationId": "get_track_deezer_track__track_id___get",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Track Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/wishlist/process/": {
      "post": {
        "tags": [
          "deezer"
        ],
        "summary": "Process Wishlist",
        "operationId": "process_wishlist_deezer_wishlist_process__post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "reprocess",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Reprocess"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/wishlist/fix/": {
      "post": {
        "tags": [
          "deezer"
        ],
        "summary": "Fix Download Date",
        "operationId": "fix_download_date_deezer_wishlist_fix__post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/wishlist/": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "Get Wishlist",
        "operationId": "get_wishlist_deezer_wishlist__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "deezer"
        ],
        "summary": "Post Wishlist",
        "operationId": "post_wishlist_deezer_wishlist__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrowserUrl"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/deezer/v2/search": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Search",
        "description": "Unified search across artists, albums, tracks.",
        "operationId": "v2_search_deezer_v2_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Index"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Search Deezer V2 Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/search/artists": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Search Artists",
        "operationId": "v2_search_artists_deezer_v2_search_artists_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Index"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Search Artists Deezer V2 Search Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/search/albums": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Search Albums",
        "operationId": "v2_search_albums_deezer_v2_search_albums_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Index"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Search Albums Deezer V2 Search Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/search/tracks": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Search Tracks",
        "operationId": "v2_search_tracks_deezer_v2_search_tracks_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Index"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Search Tracks Deezer V2 Search Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/artists/{artist_id}": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Artist Info",
        "operationId": "v2_artist_info_deezer_v2_artists__artist_id__get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Artist Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Artist Info Deezer V2 Artists  Artist Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/artists/{artist_id}/albums": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Artist Albums",
        "operationId": "v2_artist_albums_deezer_v2_artists__artist_id__albums_get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Artist Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Artist Albums Deezer V2 Artists  Artist Id  Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/artists/{artist_id}/top-tracks": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Artist Top Tracks",
        "operationId": "v2_artist_top_tracks_deezer_v2_artists__artist_id__top_tracks_get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Artist Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Artist Top Tracks Deezer V2 Artists  Artist Id  Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/artists/{artist_id}/related": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Artist Related",
        "operationId": "v2_artist_related_deezer_v2_artists__artist_id__related_get",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Artist Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Artist Related Deezer V2 Artists  Artist Id  Related Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/albums/{album_id}": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Album Info",
        "operationId": "v2_album_info_deezer_v2_albums__album_id__get",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Album Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Album Info Deezer V2 Albums  Album Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/tracks/{track_id}": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Track Info",
        "operationId": "v2_track_info_deezer_v2_tracks__track_id__get",
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Track Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Track Info Deezer V2 Tracks  Track Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/charts": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Charts",
        "description": "Global top artists / albums / tracks / playlists.",
        "operationId": "v2_charts_deezer_v2_charts_get",
        "parameters": [
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Charts Deezer V2 Charts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/charts/{genre_id}": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Charts Genre",
        "operationId": "v2_charts_genre_deezer_v2_charts__genre_id__get",
        "parameters": [
          {
            "name": "genre_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Genre Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Charts Genre Deezer V2 Charts  Genre Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/genres": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Genres",
        "operationId": "v2_genres_deezer_v2_genres_get",
        "parameters": [
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Genres Deezer V2 Genres Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/genres/{genre_id}": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Genre Info",
        "operationId": "v2_genre_info_deezer_v2_genres__genre_id__get",
        "parameters": [
          {
            "name": "genre_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Genre Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Genre Info Deezer V2 Genres  Genre Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/deezer/v2/genres/{genre_id}/artists": {
      "get": {
        "tags": [
          "deezer"
        ],
        "summary": "V2 Genre Artists",
        "operationId": "v2_genre_artists_deezer_v2_genres__genre_id__artists_get",
        "parameters": [
          {
            "name": "genre_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Genre Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response V2 Genre Artists Deezer V2 Genres  Genre Id  Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/discogs/picker/search": {
      "get": {
        "tags": [
          "discogs"
        ],
        "summary": "Discogs Picker Search",
        "description": "Picker-shaped search across artists / albums (releases).\n\nReturns ``{external_id, title, subtitle, thumbnail}`` rows for the\nLinkSourceModal. ``thumbnail`` is always ``None`` (Discogs images are\nauth-gated). ``offset`` is emulated by over-fetching + slicing.",
        "operationId": "discogs_picker_search_discogs_picker_search_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Discogs Picker Search Discogs Picker Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/itunes/picker/search": {
      "get": {
        "tags": [
          "itunes"
        ],
        "summary": "Itunes Picker Search",
        "description": "Picker-shaped search across artists / albums / tracks.\n\nReturns a list of ``{external_id, title, subtitle, thumbnail}``\nobjects for the LinkSourceModal. Apple has no artist artwork, so\nartist rows carry a ``None`` thumbnail.\n\n``offset`` is emulated (Apple's API has no paging): we fetch\n``offset + limit`` rows in one request and return the slice. Once\n``offset`` reaches the 200-result ceiling there's nothing more to\npage to and we return an empty list.",
        "operationId": "itunes_picker_search_itunes_picker_search_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Itunes Picker Search Itunes Picker Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/auth/start": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Auth Start",
        "operationId": "auth_start_lastfm_auth_start_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Auth Start Lastfm Auth Start Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/auth/callback": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Auth Callback",
        "operationId": "auth_callback_lastfm_auth_callback_get",
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Token"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/auth/disconnect": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Auth Disconnect",
        "operationId": "auth_disconnect_lastfm_auth_disconnect_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Auth Disconnect Lastfm Auth Disconnect Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/dashboard": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Dashboard",
        "description": "One-shot aggregation of stats for the home dashboard.\n\nReturns a discriminated-union shape: ``state`` is ``\"no_lastfm\"``\nwhen the user hasn't connected their LastFM account, ``\"no_scrobbles\"``\nwhen they have but haven't run an import yet, or ``\"ready\"`` with the\nfull payload otherwise.\n\n``window_days`` controls the time-scoped sections (window stats,\nchart, top lists, genres, heatmap). Pass an integer for a rolling\nwindow in days; omit or pass 0 / negative for all-time. Sections\nthat aren't time-scoped (totals, listening streak, latest scrobbles,\nmirror) are unaffected.",
        "operationId": "me_dashboard_lastfm_me_dashboard_get",
        "parameters": [
          {
            "name": "window_days",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Window Days"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Dashboard Lastfm Me Dashboard Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/dashboard/heatmap-cell": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Dashboard Heatmap Cell",
        "description": "The scrobbles behind one listening-heatmap cell.\n\nDrill-down for the dashboard heatmap: ``dow`` (0=Mon..6=Sun) \u00d7 ``hour``\n(0..23, UTC) name a cell; we return the most-recent scrobbles in it.\n``window_days`` mirrors ``/me/dashboard`` (missing \u2192 30, ``<=0`` \u2192\nall-time) so the list matches the cell the user clicked.",
        "operationId": "me_dashboard_heatmap_cell_lastfm_me_dashboard_heatmap_cell_get",
        "parameters": [
          {
            "name": "dow",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Dow"
            }
          },
          {
            "name": "hour",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Hour"
            }
          },
          {
            "name": "window_days",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Window Days"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Dashboard Heatmap Cell Lastfm Me Dashboard Heatmap Cell Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/rediscover": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Rediscover",
        "description": "Dashboard \"rediscover\" panel: tracks played a lot but not in the\nlast ``not_played_days`` (30/90/180/365/\u2026 selectable), ranked by\nall-time play count. On-demand (not part of the main dashboard\npayload) so the window can be flipped without a full reload.",
        "operationId": "me_rediscover_lastfm_me_rediscover_get",
        "parameters": [
          {
            "name": "not_played_days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 90,
              "title": "Not Played Days"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Rediscover Lastfm Me Rediscover Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/new-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me New Artists",
        "description": "Dashboard \"new artists\" panel: artists whose first-ever scrobble falls\nin the window, with the songs played by each.\n\nOn-demand like ``/me/rediscover`` so the window can be flipped without a\nfull dashboard reload. The main payload's ``new_artists_count`` /\n``new_artists_sample`` stay where they are \u2014 they feed the one-line\nactivity stat, and this is the readable version of the same fact.",
        "operationId": "me_new_artists_lastfm_me_new_artists_get",
        "parameters": [
          {
            "name": "window_days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Window Days"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "tracks_per_artist",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 5,
              "title": "Tracks Per Artist"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me New Artists Lastfm Me New Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/recent-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Recent Tracks",
        "description": "Read scrobbles from the local mirror, paginated by uts desc.\n\nLocal-only \u2014 no LastFM call. The mirror is populated by the\nbulk-import flow and the periodic refresh job.",
        "operationId": "me_recent_tracks_lastfm_me_recent_tracks_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Recent Tracks Lastfm Me Recent Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/refresh-mirror": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Refresh Mirror",
        "description": "Manually trigger a one-page mirror refresh for the current user.\n\nRuns the same ``_refresh_recent_page1`` path the periodic cron uses\n\u2014 fetches LastFM's ``user.getRecentTracks`` page 1, upserts each\nscrobble into the mirror, and fires the dedup-trigger so any new\nartist/album/track lands in the cache.\n\nSynchronous (one user, one page \u2192 ~1 sec on a warm cache, a bit\nmore on first run). Returns the count of newly-inserted scrobbles\nplus the freshly-advanced ``last_refreshed_at`` so the SPA can\nshow \"Mirror updated just now\" without a second round-trip.",
        "operationId": "me_refresh_mirror_lastfm_me_refresh_mirror_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Refresh Mirror Lastfm Me Refresh Mirror Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/recent-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Recent Tracks",
        "operationId": "user_recent_tracks_lastfm_users__username__recent_tracks_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response User Recent Tracks Lastfm Users  Username  Recent Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobbles/{scrobble_id}/canonical-link": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Stamp Scrobble Canonical",
        "description": "Write ``canonical_{artist,album,track}_id`` onto a scrobble doc.\n\nUsed by the dashboard's click handler: the SPA resolves a\nscrobble's name via Deezer search \u2192 canonical, then calls this\nso the scrobble row picks up the canonical link without an\nextra ingest/reconcile pass. Future dashboard reads find the\ncanonical_*_id already stamped and render source pills correctly.\n\nAuth: caller must own the scrobble (lastfm_username on the doc\nmust match the caller's lastfm_username). Otherwise 403.",
        "operationId": "stamp_scrobble_canonical_lastfm_me_scrobbles__scrobble_id__canonical_link_post",
        "parameters": [
          {
            "name": "scrobble_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Scrobble Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrobbleCanonicalStampPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Stamp Scrobble Canonical Lastfm Me Scrobbles  Scrobble Id  Canonical Link Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Info",
        "operationId": "me_info_lastfm_me_info_get",
        "parameters": [
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Info Lastfm Me Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/top-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Top Artists",
        "operationId": "me_top_artists_lastfm_me_top_artists_get",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Top Artists Lastfm Me Top Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Top Tracks",
        "operationId": "me_top_tracks_lastfm_me_top_tracks_get",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Top Tracks Lastfm Me Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/top-albums": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Top Albums",
        "operationId": "me_top_albums_lastfm_me_top_albums_get",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Top Albums Lastfm Me Top Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/loved-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Loved Tracks",
        "operationId": "me_loved_tracks_lastfm_me_loved_tracks_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Loved Tracks Lastfm Me Loved Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/friends": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Friends",
        "operationId": "me_friends_lastfm_me_friends_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Friends Lastfm Me Friends Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/charts/list": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Charts List",
        "operationId": "me_charts_list_lastfm_me_charts_list_get",
        "parameters": [
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Charts List Lastfm Me Charts List Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/charts/{from_ts}/{to_ts}/artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Chart Artists",
        "operationId": "me_chart_artists_lastfm_me_charts__from_ts___to_ts__artists_get",
        "parameters": [
          {
            "name": "from_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "From Ts"
            }
          },
          {
            "name": "to_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "To Ts"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Chart Artists Lastfm Me Charts  From Ts   To Ts  Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/charts/{from_ts}/{to_ts}/tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Chart Tracks",
        "operationId": "me_chart_tracks_lastfm_me_charts__from_ts___to_ts__tracks_get",
        "parameters": [
          {
            "name": "from_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "From Ts"
            }
          },
          {
            "name": "to_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "To Ts"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Chart Tracks Lastfm Me Charts  From Ts   To Ts  Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/charts/{from_ts}/{to_ts}/albums": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Chart Albums",
        "operationId": "me_chart_albums_lastfm_me_charts__from_ts___to_ts__albums_get",
        "parameters": [
          {
            "name": "from_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "From Ts"
            }
          },
          {
            "name": "to_ts",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "To Ts"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Chart Albums Lastfm Me Charts  From Ts   To Ts  Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/library/artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Library Artists",
        "operationId": "me_library_artists_lastfm_me_library_artists_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Me Library Artists Lastfm Me Library Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Info",
        "operationId": "user_info_lastfm_users__username__info_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Info Lastfm Users  Username  Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/top-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Top Artists",
        "operationId": "user_top_artists_lastfm_users__username__top_artists_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Top Artists Lastfm Users  Username  Top Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Top Tracks",
        "operationId": "user_top_tracks_lastfm_users__username__top_tracks_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Top Tracks Lastfm Users  Username  Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/top-albums": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Top Albums",
        "operationId": "user_top_albums_lastfm_users__username__top_albums_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "overall",
              "title": "Period"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Top Albums Lastfm Users  Username  Top Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/loved-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Loved Tracks",
        "operationId": "user_loved_tracks_lastfm_users__username__loved_tracks_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Loved Tracks Lastfm Users  Username  Loved Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/users/{username}/friends": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "User Friends",
        "operationId": "user_friends_lastfm_users__username__friends_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response User Friends Lastfm Users  Username  Friends Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/search": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Search",
        "description": "Pass-through (not cached) \u2014 search results aren't entity records.",
        "operationId": "artist_search_lastfm_artists_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Search Lastfm Artists Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Info",
        "operationId": "artist_info_lastfm_artists__artist__info_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Info Lastfm Artists  Artist  Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/similar": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Similar",
        "operationId": "artist_similar_lastfm_artists__artist__similar_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Similar Lastfm Artists  Artist  Similar Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/top-albums": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Top Albums",
        "operationId": "artist_top_albums_lastfm_artists__artist__top_albums_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Top Albums Lastfm Artists  Artist  Top Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Top Tracks",
        "operationId": "artist_top_tracks_lastfm_artists__artist__top_tracks_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Top Tracks Lastfm Artists  Artist  Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/top-tags": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Top Tags",
        "operationId": "artist_top_tags_lastfm_artists__artist__top_tags_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Top Tags Lastfm Artists  Artist  Top Tags Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/artists/{artist}/correction": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Artist Correction",
        "description": "Pass-through (not cached) \u2014 corrections are query-specific.",
        "operationId": "artist_correction_lastfm_artists__artist__correction_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Artist Correction Lastfm Artists  Artist  Correction Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/albums/search": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Album Search",
        "operationId": "album_search_lastfm_albums_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Album Search Lastfm Albums Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/albums/{artist}/{album}/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Album Info",
        "operationId": "album_info_lastfm_albums__artist___album__info_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "album",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Album Info Lastfm Albums  Artist   Album  Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/albums/{artist}/{album}/top-tags": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Album Top Tags",
        "operationId": "album_top_tags_lastfm_albums__artist___album__top_tags_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "album",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Album Top Tags Lastfm Albums  Artist   Album  Top Tags Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tracks/search": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Track Search",
        "operationId": "track_search_lastfm_tracks_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Track Search Lastfm Tracks Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tracks/{artist}/{track}/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Track Info",
        "operationId": "track_info_lastfm_tracks__artist___track__info_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "track",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Track Info Lastfm Tracks  Artist   Track  Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tracks/{artist}/{track}/similar": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Track Similar",
        "operationId": "track_similar_lastfm_tracks__artist___track__similar_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "track",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Track Similar Lastfm Tracks  Artist   Track  Similar Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tracks/{artist}/{track}/top-tags": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Track Top Tags",
        "operationId": "track_top_tags_lastfm_tracks__artist___track__top_tags_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "track",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Track Top Tags Lastfm Tracks  Artist   Track  Top Tags Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tracks/{artist}/{track}/correction": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Track Correction",
        "operationId": "track_correction_lastfm_tracks__artist___track__correction_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "track",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Track Correction Lastfm Tracks  Artist   Track  Correction Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/picker/search": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Lastfm Picker Search",
        "description": "Picker-shaped search across artists / albums / tracks.\n\nReturns a list of ``{external_id, title, subtitle, thumbnail}``\nobjects ready for the LinkSourceModal. ``external_id`` is the\ncanonical LastFM ref shape \u2014 lowercased name (artists) or\n``<artist>::<name>`` (albums + tracks) \u2014 produced by the same\nhelpers the resolver uses.\n\nWhy not consume LastFM's raw search response on the frontend? The\nexternal_id construction has to match the resolver's\n:func:`lastfm_artist_id`/:func:`lastfm_album_id`/:func:`lastfm_track_id`\nexactly, or the picker's \"Link\" action would write a ref that no\nsubsequent lookup finds. Single source of truth \u2192 backend.\n\n``offset`` powers the picker's \"Load more\": LastFM's search methods\npaginate by 1-based ``page``, so we translate ``offset`` (which the\nSPA advances in ``limit``-sized steps) to ``page = offset // limit + 1``.",
        "operationId": "lastfm_picker_search_lastfm_picker_search_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Lastfm Picker Search Lastfm Picker Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/info": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Info",
        "operationId": "tag_info_lastfm_tags__tag__info_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Info Lastfm Tags  Tag  Info Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/similar": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Similar",
        "operationId": "tag_similar_lastfm_tags__tag__similar_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Similar Lastfm Tags  Tag  Similar Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/top-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Top Artists",
        "operationId": "tag_top_artists_lastfm_tags__tag__top_artists_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Top Artists Lastfm Tags  Tag  Top Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Top Tracks",
        "operationId": "tag_top_tracks_lastfm_tags__tag__top_tracks_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Top Tracks Lastfm Tags  Tag  Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/top-albums": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Top Albums",
        "operationId": "tag_top_albums_lastfm_tags__tag__top_albums_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Top Albums Lastfm Tags  Tag  Top Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/tags/{tag}/weekly-chart-list": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Tag Weekly Chart List",
        "operationId": "tag_weekly_chart_list_lastfm_tags__tag__weekly_chart_list_get",
        "parameters": [
          {
            "name": "tag",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Tag"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Tag Weekly Chart List Lastfm Tags  Tag  Weekly Chart List Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/charts/top-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Chart Top Artists",
        "operationId": "chart_top_artists_lastfm_charts_top_artists_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Chart Top Artists Lastfm Charts Top Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/charts/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Chart Top Tracks",
        "operationId": "chart_top_tracks_lastfm_charts_top_tracks_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Chart Top Tracks Lastfm Charts Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/charts/top-tags": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Chart Top Tags",
        "operationId": "chart_top_tags_lastfm_charts_top_tags_get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Chart Top Tags Lastfm Charts Top Tags Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/geo/{country}/top-artists": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Geo Top Artists",
        "operationId": "geo_top_artists_lastfm_geo__country__top_artists_get",
        "parameters": [
          {
            "name": "country",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Country"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Geo Top Artists Lastfm Geo  Country  Top Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/geo/{country}/top-tracks": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Geo Top Tracks",
        "operationId": "geo_top_tracks_lastfm_geo__country__top_tracks_get",
        "parameters": [
          {
            "name": "country",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Country"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Geo Top Tracks Lastfm Geo  Country  Top Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/love": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Love",
        "operationId": "me_love_lastfm_me_love_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoveTrackPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Love Lastfm Me Love Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/unlove": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Unlove",
        "operationId": "me_unlove_lastfm_me_unlove_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoveTrackPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Unlove Lastfm Me Unlove Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobble": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Scrobble",
        "description": "Submit a scrobble to LastFM. The next periodic refresh picks it up.",
        "operationId": "me_scrobble_lastfm_me_scrobble_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrobblePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Scrobble Lastfm Me Scrobble Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/now-playing": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Now Playing",
        "operationId": "me_now_playing_lastfm_me_now_playing_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrobblePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Now Playing Lastfm Me Now Playing Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/artists": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Favorite Artist",
        "description": "Mark an artist as favorite. Auto-fetches the artist into the catalog\nif it isn't already cached (so the favorite always has hydration data).",
        "operationId": "favorite_artist_lastfm_me_favorites_artists_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FavoriteArtistPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Artist Lastfm Me Favorites Artists Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "List Favorite Artists",
        "operationId": "list_favorite_artists_lastfm_me_favorites_artists_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Artists Lastfm Me Favorites Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/artists/{target_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Unfavorite Artist",
        "operationId": "unfavorite_artist_lastfm_me_favorites_artists__target_id__delete",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Artist Lastfm Me Favorites Artists  Target Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/albums": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Favorite Album",
        "operationId": "favorite_album_lastfm_me_favorites_albums_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FavoriteAlbumPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Album Lastfm Me Favorites Albums Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "List Favorite Albums",
        "operationId": "list_favorite_albums_lastfm_me_favorites_albums_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Albums Lastfm Me Favorites Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/albums/{target_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Unfavorite Album",
        "operationId": "unfavorite_album_lastfm_me_favorites_albums__target_id__delete",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Album Lastfm Me Favorites Albums  Target Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/tracks": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Favorite Track",
        "operationId": "favorite_track_lastfm_me_favorites_tracks_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FavoriteTrackPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Track Lastfm Me Favorites Tracks Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "List Favorite Tracks",
        "operationId": "list_favorite_tracks_lastfm_me_favorites_tracks_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Tracks Lastfm Me Favorites Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/favorites/tracks/{target_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Unfavorite Track",
        "operationId": "unfavorite_track_lastfm_me_favorites_tracks__target_id__delete",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Track Lastfm Me Favorites Tracks  Target Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/albums/wishlist": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Add To Wishlist",
        "operationId": "add_to_wishlist_lastfm_me_albums_wishlist_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AlbumStatusPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Add To Wishlist Lastfm Me Albums Wishlist Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "List Wishlist",
        "operationId": "list_wishlist_lastfm_me_albums_wishlist_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Wishlist Lastfm Me Albums Wishlist Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/albums/wishlist/{target_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Remove From Wishlist",
        "operationId": "remove_from_wishlist_lastfm_me_albums_wishlist__target_id__delete",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Remove From Wishlist Lastfm Me Albums Wishlist  Target Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/albums/owned": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Mark Owned",
        "description": "Mark an album as owned. If it was on the wishlist, this transitions\nit (preserving ``wishlisted_at`` as history).",
        "operationId": "mark_owned_lastfm_me_albums_owned_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AlbumStatusPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Mark Owned Lastfm Me Albums Owned Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "List Owned",
        "operationId": "list_owned_lastfm_me_albums_owned_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Owned Lastfm Me Albums Owned Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/albums/owned/{target_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Mark Not Owned",
        "operationId": "mark_not_owned_lastfm_me_albums_owned__target_id__delete",
        "parameters": [
          {
            "name": "target_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Target Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Mark Not Owned Lastfm Me Albums Owned  Target Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/artists/{artist}/stats": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Artist Stats",
        "operationId": "me_artist_stats_lastfm_me_artists__artist__stats_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Artist Stats Lastfm Me Artists  Artist  Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/albums/{artist}/{album}/stats": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Album Stats",
        "operationId": "me_album_stats_lastfm_me_albums__artist___album__stats_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "album",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Album Stats Lastfm Me Albums  Artist   Album  Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/tracks/{artist}/{track}/stats": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Track Stats",
        "operationId": "me_track_stats_lastfm_me_tracks__artist___track__stats_get",
        "parameters": [
          {
            "name": "artist",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist"
            }
          },
          {
            "name": "track",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Track"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Track Stats Lastfm Me Tracks  Artist   Track  Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobbles/bulk-import": {
      "post": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Scrobbles Bulk Import",
        "operationId": "me_scrobbles_bulk_import_lastfm_me_scrobbles_bulk_import_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkImportPayload"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Scrobbles Bulk Import Lastfm Me Scrobbles Bulk Import Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobbles/bulk-import/current": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Scrobbles Bulk Import Current",
        "operationId": "me_scrobbles_bulk_import_current_lastfm_me_scrobbles_bulk_import_current_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "additionalProperties": true
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Response Me Scrobbles Bulk Import Current Lastfm Me Scrobbles Bulk Import Current Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobbles/bulk-import/history": {
      "get": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Scrobbles Bulk Import History",
        "operationId": "me_scrobbles_bulk_import_history_lastfm_me_scrobbles_bulk_import_history_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Me Scrobbles Bulk Import History Lastfm Me Scrobbles Bulk Import History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lastfm/me/scrobbles/bulk-import/{task_id}": {
      "delete": {
        "tags": [
          "lastfm"
        ],
        "summary": "Me Scrobbles Bulk Import Cancel",
        "operationId": "me_scrobbles_bulk_import_cancel_lastfm_me_scrobbles_bulk_import__task_id__delete",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Scrobbles Bulk Import Cancel Lastfm Me Scrobbles Bulk Import  Task Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/ask": {
      "get": {
        "tags": [
          "library"
        ],
        "summary": "Library Ask",
        "description": "Interpret a plain-language library request into query params.\n\nTranslates e.g. *\"hi-res jazz albums I haven't played in two years\"*\ninto the ``kind`` / ``sort`` / ``filter`` / ``genre`` / ``q`` params the\n``/library/{kind}`` endpoints already accept \u2014 the model returns\n**filters, never entity names**, and every value is validated against\nthe same enums the router enforces.\n\nAlways 200. ``state`` is ``ok`` (with ``query``), ``not_configured``\n(no DeepSeek key \u2014 the SPA hides the ask-bar) or ``failed`` (upstream\nhiccup \u2014 the SPA keeps the manual filter controls). Never a 500: this\nis an assist on top of a working UI, not a dependency of it.",
        "operationId": "library_ask_library_ask_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Library Ask Library Ask Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/playlist/generate": {
      "post": {
        "tags": [
          "library"
        ],
        "summary": "Library Generate Playlist",
        "description": "Propose a playlist from the user's OWN library (roadmap #2).\n\nBody: ``{\"request\": str, \"genre\": str|null, \"max_tracks\": int}``.\n\nRetrieval-first \u2014 we hand the model only playable canonical tracks and\nit returns *indexes* into that list, so it cannot introduce music we\ndon't own. Every returned index is validated back to a canonical id.\n\nThis only **proposes**; nothing is written to Plex until the client\nconfirms via ``/library/playlist/create``. Always 200 with a ``state``\n(``ok`` / ``not_configured`` / ``no_candidates`` / ``failed``).",
        "operationId": "library_generate_playlist_library_playlist_generate_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true,
                "title": "Payload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Library Generate Playlist Library Playlist Generate Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/playlist/create": {
      "post": {
        "tags": [
          "library"
        ],
        "summary": "Library Create Playlist",
        "description": "Materialise a confirmed proposal as a Plex playlist.\n\nBody: ``{\"title\": str, \"canonical_track_ids\": [str, ...]}`` \u2014 the ids\ncome straight from a ``/generate`` proposal the user accepted, so the\nwrite path never trusts model output directly.",
        "operationId": "library_create_playlist_library_playlist_create_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true,
                "title": "Payload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Library Create Playlist Library Playlist Create Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/genres": {
      "get": {
        "tags": [
          "library"
        ],
        "summary": "List Library Genres",
        "description": "Distinct canonical genres present in the library + album counts.\n\nAggregated over canonical albums (genres live at the album level \u2014\nthe per-track signal is sparse), newest-merged excluded, sorted by\ncount desc. Powers the Genres page: each genre filters the Library\n(``?genre=``) and can seed a genre radio. Declared before the\n``/library/{kind}`` routes are matched (all literal, so order is\nmoot, but kept adjacent for clarity). ``limit`` 0 = all.",
        "operationId": "list_library_genres_library_genres_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Library Genres Library Genres Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/artists": {
      "get": {
        "tags": [
          "library"
        ],
        "summary": "List Library Artists",
        "operationId": "list_library_artists_library_artists_get",
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "recent",
                "name",
                "source_count"
              ],
              "type": "string",
              "default": "recent",
              "title": "Sort"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "missing_deezer",
                    "missing_musicbrainz",
                    "missing_plex",
                    "only_plex",
                    "no_scrobbles",
                    "favorites",
                    "lossless",
                    "hi_res"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Filter"
            }
          },
          {
            "name": "genre",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Genre"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Page Size"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Library Artists Library Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/albums": {
      "get": {
        "tags": [
          "library"
        ],
        "summary": "List Library Albums",
        "operationId": "list_library_albums_library_albums_get",
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "recent",
                "name",
                "source_count"
              ],
              "type": "string",
              "default": "recent",
              "title": "Sort"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "missing_deezer",
                    "missing_musicbrainz",
                    "missing_plex",
                    "only_plex",
                    "no_scrobbles",
                    "favorites",
                    "lossless",
                    "hi_res"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Filter"
            }
          },
          {
            "name": "genre",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Genre"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Page Size"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Library Albums Library Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/library/tracks": {
      "get": {
        "tags": [
          "library"
        ],
        "summary": "List Library Tracks",
        "operationId": "list_library_tracks_library_tracks_get",
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "recent",
                "name",
                "source_count"
              ],
              "type": "string",
              "default": "recent",
              "title": "Sort"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "missing_deezer",
                    "missing_musicbrainz",
                    "missing_plex",
                    "only_plex",
                    "no_scrobbles",
                    "favorites",
                    "lossless",
                    "hi_res"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Filter"
            }
          },
          {
            "name": "genre",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Genre"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Page Size"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Library Tracks Library Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/artists": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Favorite Artist",
        "operationId": "favorite_artist_me_favorites_artists_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityRef"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Artist Me Favorites Artists Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Favorite Artists",
        "operationId": "list_favorite_artists_me_favorites_artists_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Artists Me Favorites Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/artists/{canonical_id}": {
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Unfavorite Artist",
        "operationId": "unfavorite_artist_me_favorites_artists__canonical_id__delete",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Artist Me Favorites Artists  Canonical Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/albums": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Favorite Album",
        "operationId": "favorite_album_me_favorites_albums_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityRef"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Album Me Favorites Albums Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Favorite Albums",
        "operationId": "list_favorite_albums_me_favorites_albums_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Albums Me Favorites Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/albums/{canonical_id}": {
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Unfavorite Album",
        "operationId": "unfavorite_album_me_favorites_albums__canonical_id__delete",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Album Me Favorites Albums  Canonical Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/tracks": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Favorite Track",
        "operationId": "favorite_track_me_favorites_tracks_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityRef"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Favorite Track Me Favorites Tracks Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Favorite Tracks",
        "operationId": "list_favorite_tracks_me_favorites_tracks_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Favorite Tracks Me Favorites Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/favorites/tracks/{canonical_id}": {
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Unfavorite Track",
        "operationId": "unfavorite_track_me_favorites_tracks__canonical_id__delete",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unfavorite Track Me Favorites Tracks  Canonical Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/albums/wishlist": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Add To Wishlist",
        "operationId": "add_to_wishlist_me_albums_wishlist_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityRef"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Add To Wishlist Me Albums Wishlist Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Wishlist",
        "operationId": "list_wishlist_me_albums_wishlist_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Wishlist Me Albums Wishlist Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/albums/wishlist/{canonical_id}": {
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Remove From Wishlist",
        "operationId": "remove_from_wishlist_me_albums_wishlist__canonical_id__delete",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Remove From Wishlist Me Albums Wishlist  Canonical Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/albums/owned": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Mark Owned",
        "operationId": "mark_owned_me_albums_owned_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityRef"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Mark Owned Me Albums Owned Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Owned",
        "operationId": "list_owned_me_albums_owned_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Owned Me Albums Owned Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/albums/owned/{canonical_id}": {
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Mark Not Owned",
        "operationId": "mark_not_owned_me_albums_owned__canonical_id__delete",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Mark Not Owned Me Albums Owned  Canonical Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/comments/counts": {
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Comment Counts",
        "description": "Batch visible-comment counts: ``{\"<kind>::<id>\": n}`` for the\nrequested items. One round-trip for list-row indicators.",
        "operationId": "comment_counts_me_comments_counts_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentCountsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "integer"
                  },
                  "title": "Response Comment Counts Me Comments Counts Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/comments": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List My Comments",
        "description": "All of the caller's notes, newest-first (the My Notes page). Each\nnote carries an ``item`` summary (title / subtitle / cover) so the\npage can render a real entity row, not a bare canonical id.",
        "operationId": "list_my_comments_me_comments_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List My Comments Me Comments Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/comments/{kind}/{canonical_id}": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "List Item Comments",
        "description": "The thread on one entity, oldest-first. Admins see everyone's\nnotes; regular users see only their own.",
        "operationId": "list_item_comments_me_comments__kind___canonical_id__get",
        "parameters": [
          {
            "name": "kind",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Item Comments Me Comments  Kind   Canonical Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "me"
        ],
        "summary": "Add Item Comment",
        "operationId": "add_item_comment_me_comments__kind___canonical_id__post",
        "parameters": [
          {
            "name": "kind",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Add Item Comment Me Comments  Kind   Canonical Id  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/comments/{comment_id}": {
      "patch": {
        "tags": [
          "me"
        ],
        "summary": "Edit Comment",
        "description": "Edit own note. Author-scoped \u2014 404 if it isn't yours (admins\nincluded; they can read others' but not mutate them).",
        "operationId": "edit_comment_me_comments__comment_id__patch",
        "parameters": [
          {
            "name": "comment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Comment Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Edit Comment Me Comments  Comment Id  Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "me"
        ],
        "summary": "Delete Comment",
        "description": "Delete own note. Author-scoped.",
        "operationId": "delete_comment_me_comments__comment_id__delete",
        "parameters": [
          {
            "name": "comment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Comment Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete Comment Me Comments  Comment Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/tasks/{task_id}": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "Get My Task",
        "description": "Poll a background task that *this* user started.\n\nReturns the same shape as ``GET /admin/task-history/{id}`` but\nrefuses to leak rows started by anyone else. The composable\n``useBackgroundTask`` polls this endpoint every 2s for SPA-driven\nsync flows where the caller is the task owner.",
        "operationId": "get_my_task_me_tasks__task_id__get",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get My Task Me Tasks  Task Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/stats/artists/{canonical_id}": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "Stats Artist",
        "operationId": "stats_artist_me_stats_artists__canonical_id__get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Stats Artist Me Stats Artists  Canonical Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/stats/albums/{canonical_id}": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "Stats Album",
        "operationId": "stats_album_me_stats_albums__canonical_id__get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Stats Album Me Stats Albums  Canonical Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/stats/tracks/{canonical_id}": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "Stats Track",
        "operationId": "stats_track_me_stats_tracks__canonical_id__get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Stats Track Me Stats Tracks  Canonical Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/artists": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Artists",
        "operationId": "search_artists_musicbrainz_search_artists_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Artists Musicbrainz Search Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/release-groups": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Release Groups",
        "operationId": "search_release_groups_musicbrainz_search_release_groups_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Release Groups Musicbrainz Search Release Groups Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/releases": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Releases",
        "operationId": "search_releases_musicbrainz_search_releases_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Releases Musicbrainz Search Releases Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/recordings": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Recordings",
        "operationId": "search_recordings_musicbrainz_search_recordings_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Recordings Musicbrainz Search Recordings Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/labels": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Labels",
        "operationId": "search_labels_musicbrainz_search_labels_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Labels Musicbrainz Search Labels Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/search/works": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Search Works",
        "operationId": "search_works_musicbrainz_search_works_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Search Works Musicbrainz Search Works Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/artists/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Artist",
        "operationId": "get_artist_musicbrainz_artists__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Artist Musicbrainz Artists  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/artists/{mbid}/release-groups": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Browse Artist Release Groups",
        "operationId": "browse_artist_release_groups_musicbrainz_artists__mbid__release_groups_get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Browse Artist Release Groups Musicbrainz Artists  Mbid  Release Groups Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/release-groups/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Release Group",
        "operationId": "get_release_group_musicbrainz_release_groups__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Release Group Musicbrainz Release Groups  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/release-groups/{mbid}/cover-art": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Release Group Cover Art",
        "operationId": "get_release_group_cover_art_musicbrainz_release_groups__mbid__cover_art_get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Release Group Cover Art Musicbrainz Release Groups  Mbid  Cover Art Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/releases/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Release",
        "operationId": "get_release_musicbrainz_releases__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Release Musicbrainz Releases  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/releases/{mbid}/cover-art": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Release Cover Art",
        "operationId": "get_release_cover_art_musicbrainz_releases__mbid__cover_art_get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Release Cover Art Musicbrainz Releases  Mbid  Cover Art Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/releases/by-barcode/{upc}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Release By Barcode",
        "description": "Cross-reference shortcut: UPC \u2192 MB release.\n\nUsed by the Deezer enrichment path. Returns the canonical release\ndoc on hit, 404 on miss. Cached after first lookup.",
        "operationId": "get_release_by_barcode_musicbrainz_releases_by_barcode__upc__get",
        "parameters": [
          {
            "name": "upc",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upc"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Release By Barcode Musicbrainz Releases By Barcode  Upc  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/recordings/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Recording",
        "operationId": "get_recording_musicbrainz_recordings__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Recording Musicbrainz Recordings  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/labels/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Label",
        "operationId": "get_label_musicbrainz_labels__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Label Musicbrainz Labels  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/works/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Work",
        "operationId": "get_work_musicbrainz_works__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Work Musicbrainz Works  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/areas/{mbid}": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Get Area",
        "operationId": "get_area_musicbrainz_areas__mbid__get",
        "parameters": [
          {
            "name": "mbid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Mbid"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Get Area Musicbrainz Areas  Mbid  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/admin/enrich-deezer-albums": {
      "post": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Trigger Enrichment",
        "description": "Kick off one Deezer\u2192MB enrichment batch in the background.\n\nFire-and-forget: returns a ``task_id`` immediately and runs the\nwork on the event loop. The SPA polls\n``GET /admin/task-history/{task_id}`` for progress + final\nsummary.\n\nWhy background: MB's 1 rps limit \u00d7 ~2 calls per album means\n``ENRICH_BATCH=30`` typically takes 60-90 seconds \u2014 well past the\nSPA's 15s HTTP client timeout. Cron-driven runs aren't affected\n(they're already off the request path).",
        "operationId": "trigger_enrichment_musicbrainz_admin_enrich_deezer_albums_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Trigger Enrichment Musicbrainz Admin Enrich Deezer Albums Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/admin/isrc-link-status": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Isrc Link Status",
        "description": "Coverage for the ISRC\u2192MB-recording bridge.\n\nReports how many canonical tracks have an ISRC, how many of those\nalready carry a MusicBrainz recording ref, and the remaining\nbacklog. This is the prerequisite for the AcousticBrainz backfill\n(AB is keyed by recording MBID), so the admin can see whether\nthere's work to do before kicking AB.",
        "operationId": "isrc_link_status_musicbrainz_admin_isrc_link_status_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Isrc Link Status Musicbrainz Admin Isrc Link Status Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/admin/link-isrcs": {
      "post": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Trigger Isrc Link",
        "description": "Kick off one ISRC\u2192MB-recording linking batch in the background.\n\nFor each canonical track with an ISRC but no MusicBrainz recording\nref, looks up the recording by ISRC and binds it. Stamping the MB\nref is what makes the track eligible for the AcousticBrainz\nbackfill. MusicBrainz-throttled (1 rps \u00d7 2 calls/track), so the\nwork is offloaded to a background task and the SPA polls\n``/admin/task-history/{task_id}``.",
        "operationId": "trigger_isrc_link_musicbrainz_admin_link_isrcs_post",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Trigger Isrc Link Musicbrainz Admin Link Isrcs Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/musicbrainz/admin/health": {
      "get": {
        "tags": [
          "musicbrainz"
        ],
        "summary": "Admin Health",
        "description": "Diagnostic snapshot of the MB integration for the admin panel.\n\nCheap reads + one optional live ping:\n\n* **Config**: UA, rate limit, cron expression (or empty if disabled)\n* **Mongo counts** per ``musicbrainz_*`` collection\n* **Enrichment progress** against the Deezer catalog (UPC-bridge\n  coverage)\n* **Last few cron runs** from ``task_history`` for at-a-glance\n  \"did the cron run? did it succeed?\" answers\n* **Live ping** against plex.tv-style\u2026wait, MB \u2014 the test fetches\n  a known artist (Daft Punk) to confirm the API + UA combo are\n  working. Failures here mean the user-agent is being rejected or\n  the network is blocked.",
        "operationId": "admin_health_musicbrainz_admin_health_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "title": "Response Admin Health Musicbrainz Admin Health Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/overview": {
      "get": {
        "tags": [
          "overview"
        ],
        "summary": "Get Overview",
        "description": "Activity feed for a time window + play-scope.\n\n``window`` is days (7 / 30). ``scope`` controls the play-based cards\n(discoveries / trending): ``me`` = the caller's LastFM scrobbles,\n``everyone`` = library-wide. ``added`` is always whole-library;\n``activity`` is always the caller's own wishlist/favorites.\n\nThe queries are synchronous PyMongo (and the discoveries aggregation\nscans scrobbles to find true first-plays), so we offload to a worker\nthread to keep the event loop responsive.",
        "operationId": "get_overview_overview_get",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "7",
                "30"
              ],
              "type": "string",
              "default": "7",
              "title": "Window"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "me",
                "everyone"
              ],
              "type": "string",
              "default": "me",
              "title": "Scope"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Overview Overview Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Get My Link",
        "description": "Public link state for the caller.\n\n``link`` is null when not linked. ``has_pending_pin`` is true when\na PIN flow is mid-air \u2014 the SPA uses it to know whether to resume\npolling on settings page refresh.",
        "operationId": "get_my_link_plex_me_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get My Link Plex Me Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "plex"
        ],
        "summary": "Unlink",
        "description": "Clear the caller's Plex link.\n\nLibrary data (global) is untouched \u2014 disconnecting just drops the\nidentity mapping; if the same user re-links later they pick up the\nexisting mirror as-is.",
        "operationId": "unlink_plex_me_delete",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unlink Plex Me Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/auth/start": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Start Pin",
        "description": "Kick off a fresh PIN-based link flow.\n\nReturns ``{pin_id, code, auth_url, expires_at}``. The SPA opens\n``auth_url`` in a new tab; the user signs in there; we poll via\n``POST /me/auth/finish``.",
        "operationId": "start_pin_plex_me_auth_start_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Start Pin Plex Me Auth Start Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/auth/finish": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Finish Pin",
        "description": "Poll for completion of the caller's pending PIN.\n\nOne poll per call. SPA loops every ~2s until ``status != 'pending'``.\nReturns one of:\n  ``{status: 'pending'}`` \u2014 keep polling\n  ``{status: 'completed', link}`` \u2014 done; the user is linked\n  ``{status: 'expired', error}`` \u2014 PIN expired before completion\n  ``{status: 'no_pending_pin'}`` \u2014 nothing to poll (start one first)",
        "operationId": "finish_pin_plex_me_auth_finish_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Finish Pin Plex Me Auth Finish Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/auth/cancel": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Cancel Pin",
        "description": "Drop the pending PIN \u2014 call when the user closes the popup.",
        "operationId": "cancel_pin_plex_me_auth_cancel_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Cancel Pin Plex Me Auth Cancel Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/home-users": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Home Users",
        "description": "List the caller's Plex Home users (excluding the caller).\n\n412 when the caller hasn't linked Plex. 401 if the stored token\nwas revoked plex-side since last use; SPA should suggest a\nre-link in that case.",
        "operationId": "list_home_users_plex_me_home_users_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Home Users Plex Me Home Users Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/home-users/{home_user_id}/provision": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Provision Home User",
        "description": "Create an app account for a Plex Home user.\n\nStatus codes:\n  * 201 \u2014 created. Body is the new user's public profile.\n  * 400 \u2014 Plex returned a 4xx on switch (wrong PIN, no such Home\n    user). Body's ``detail`` carries the plex.tv message.\n  * 401 \u2014 owner's stored Plex token was rejected.\n  * 409 \u2014 requested ``new_username`` already exists.\n  * 412 \u2014 owner hasn't linked Plex yet.\n  * 502 \u2014 Plex.tv transport / unexpected upstream error.",
        "operationId": "provision_home_user_plex_me_home_users__home_user_id__provision_post",
        "parameters": [
          {
            "name": "home_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Home User Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProvisionHomeUserPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Provision Home User Plex Me Home Users  Home User Id  Provision Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/playlists": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List My Playlists",
        "description": "List the caller's synced playlists.\n\nReturns plain catalog rows (no items embedded in the listing \u2014 the\ndetail endpoint serves those). Optional ``playlist_type=audio``\n/``video`` /``photo`` filter for the SPA's tab strip.",
        "operationId": "list_my_playlists_plex_me_playlists_get",
        "parameters": [
          {
            "name": "playlist_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Playlist Type"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List My Playlists Plex Me Playlists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/playlists/sync": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Sync My Playlists",
        "description": "Fire-and-forget sync of the caller's Plex playlists.\n\nRequires the caller to have linked Plex via the PIN flow first;\nreturns 412 Precondition Failed otherwise so the SPA can surface\na \"Link your Plex account first\" CTA.",
        "operationId": "sync_my_playlists_plex_me_playlists_sync_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Sync My Playlists Plex Me Playlists Sync Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/favorites-playlist/sync": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Sync My Favorites Playlist",
        "description": "Reconcile the caller's favorite tracks against their per-user\nPlex playlist (``\"<username> - Favorites\"``).\n\nSingle-track add/remove already happens automatically inside the\nfavorite/unfavorite endpoints. This route is the manual catch-up\npath: useful right after enabling the feature (to backfill\nexisting favorites), and as a \"Sync now\" button on Settings.\n\nSide-effect of a successful first call: flips\n``preferences.plex_favorites_sync_enabled`` on if it isn't\nalready, since the user actively asked for it. The toggle in\nSettings just calls this endpoint.\n\n``force_recreate=true`` deletes any existing playlist and rebuilds\nfrom the current favorites list. Use when the playlist is\ncorrupted manually on Plex side.\n\n412 if the user hasn't linked Plex.",
        "operationId": "sync_my_favorites_playlist_plex_me_favorites_playlist_sync_post",
        "parameters": [
          {
            "name": "force_recreate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Force Recreate"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Sync My Favorites Playlist Plex Me Favorites Playlist Sync Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/playlists/{playlist_id}/cover": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Get My Playlist Cover",
        "description": "Stream the playlist's composite cover image from Plex.\n\nThe composite is Plex-side artwork (4 album covers stitched\ntogether for audio playlists, item-art collage for video). Its URL\nis on the playlist row but it needs an ``X-Plex-Token`` to fetch\n\u2014 we can't put that in the browser (CORS + token leak), so we\nproxy the same way the audio streaming endpoint does.\n\nReturns 404 when the playlist doesn't have a composite_url\n(empty playlists, some smart-playlist variants). The SPA falls\nback to a typed emoji placeholder.\n\nOwnership: caller must own the playlist (same scoping as the\ndetail endpoint). Cover image goes through unauthenticated by\nthe browser's image fetch, so this gate matters.\n\n**Route ordering matters**: declared above\n``/me/playlists/{playlist_id:path}`` because that catch-all\nwould otherwise match ``playlist_id='<id>/cover'``.",
        "operationId": "get_my_playlist_cover_plex_me_playlists__playlist_id__cover_get",
        "parameters": [
          {
            "name": "playlist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Playlist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/playlists/{playlist_id}": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Get My Playlist",
        "description": "Single playlist with embedded items + per-item canonical resolution.\n\nFor each audio item we look up\n``track_external_refs._id == 'plex::<server_id>::<rating_key>'``\nin one ``$in`` query and attach ``canonical_track_id`` to the\nmatching items. The SPA uses that to render source pills and wire\ninline playback to ``/plex/play/track/<canonical_id>``.\n\n``playlist_id`` is the compound key ``<server_id>::<rating_key>``,\nwhich contains a ``:`` \u2014 declared as ``:path`` so FastAPI doesn't\ntruncate.",
        "operationId": "get_my_playlist_plex_me_playlists__playlist_id__get",
        "parameters": [
          {
            "name": "playlist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Playlist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get My Playlist Plex Me Playlists  Playlist Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/me/playlists/{playlist_id}/refresh": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Refresh My Playlist",
        "description": "Re-fetch a single playlist's items from Plex.\n\nSmart playlists are Plex-side filters; their contents can change\nwithout the playlist row's ``updatedAt`` advancing. The detail\nview auto-calls this on mount so the user sees current state.\nNon-smart playlists also work here (just a refetch + overwrite).",
        "operationId": "refresh_my_playlist_plex_me_playlists__playlist_id__refresh_post",
        "parameters": [
          {
            "name": "playlist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Playlist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Refresh My Playlist Plex Me Playlists  Playlist Id  Refresh Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Libraries",
        "description": "All libraries from the global Plex server (cached). Any\nauthenticated user can read.",
        "operationId": "list_libraries_plex_libraries_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Libraries Plex Libraries Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/artists": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Artists",
        "operationId": "list_artists_plex_libraries__section_id__artists_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Artists Plex Libraries  Section Id  Artists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/albums": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Albums",
        "operationId": "list_albums_plex_libraries__section_id__albums_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Albums Plex Libraries  Section Id  Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/tracks": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Tracks",
        "operationId": "list_tracks_plex_libraries__section_id__tracks_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Tracks Plex Libraries  Section Id  Tracks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/library/search": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Library Search",
        "description": "Substring search across the user's synced Plex music library.\n\nPowers the \"Add Plex link\" modal on canonical detail views.\nActive items only (soft-deleted Plex docs are excluded \u2014 the\ncanonical layer wouldn't merge from them anyway).\n\n``offset`` skips that many matches for the picker's \"Load more\".",
        "operationId": "library_search_plex_library_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "album",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Library Search Plex Library Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/movies": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Movies",
        "operationId": "list_movies_plex_libraries__section_id__movies_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Movies Plex Libraries  Section Id  Movies Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/shows": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Shows",
        "operationId": "list_shows_plex_libraries__section_id__shows_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Shows Plex Libraries  Section Id  Shows Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/seasons": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Seasons",
        "operationId": "list_seasons_plex_libraries__section_id__seasons_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Seasons Plex Libraries  Section Id  Seasons Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/libraries/{section_id}/episodes": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Episodes",
        "operationId": "list_episodes_plex_libraries__section_id__episodes_get",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Episodes Plex Libraries  Section Id  Episodes Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/track/{canonical_id}/details": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Get Plex Track Details",
        "description": "Project the Plex-side metadata for a canonical track for display.\n\nUsed by TrackDetailView to render the \"\ud83c\udfb5 Plex (full) \u00b7 FLAC 16/44.1\n\u00b7 23.4 MB\" one-liner + the expandable \"Plex details\" block (plays,\nlast played, added, star rating).\n\nReturns 404 if the canonical doesn't have a (live) Plex link. The SPA\nsuppresses the details block in that case. Resolves the freshest live\n``plex_tracks`` row (see :func:`_resolve_live_plex_track_doc`) so a\ntrack whose file was replaced shows the *new* file's details rather\nthan a stale, soft-deleted row.",
        "operationId": "get_plex_track_details_plex_track__canonical_id__details_get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Plex Track Details Plex Track  Canonical Id  Details Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/play/album-tracks/{canonical_album_id}/details": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Plex Album Track Details",
        "description": "Return ``{canonical_track_id: PlexTrackDetails}`` for every track\non this album that's Plex-linked.\n\nBatch version of ``/plex/track/{canonical_id}/details`` \u2014 avoids\nthe N+1 problem when the SPA needs the quality one-liner for\nevery row of an album tracklist. Three queries total regardless\nof tracklist size:\n\n  1. ``media_tracks`` with ``album_id`` + ``sources.plex`` \u2014 gets\n     the canonical-track set.\n  2. ``track_external_refs`` with ``$in`` on those canonical_ids\n     + source=plex \u2014 gets the compound Plex external_ids.\n  3. ``plex_tracks`` with ``$in`` on those external_ids \u2014 fetches\n     the raw payloads.",
        "operationId": "list_plex_album_track_details_plex_play_album_tracks__canonical_album_id__details_get",
        "parameters": [
          {
            "name": "canonical_album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Plex Album Track Details Plex Play Album Tracks  Canonical Album Id  Details Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/play/album-tracks/{canonical_album_id}": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "List Plex Playable Tracks",
        "description": "Return Plex-playable canonical tracks on this album, keyed three ways.\n\nThe album-detail tracklist iterates Deezer track rows (that's where\ntitles + 30s previews come from), but Plex play needs the canonical\nULID. Three lookup paths, tried in order by the SPA, so a row can\nstill resolve when the easier matchers don't apply:\n\n  * ``by_deezer_id`` \u2014 ``{deezer_track_id: canonical_track_id}``.\n    The fast path: stamped via the denormalised ``deezer_id`` field\n    on the canonical track. Only fires for canonicals that already\n    have a Deezer ref.\n  * ``by_title_folded`` \u2014 ``{title_folded: canonical_track_id}``.\n    Fallback for canonicals minted from a non-Deezer source (Plex /\n    MB / LastFM) where ``deezer_id`` is empty. The SPA folds the\n    Deezer row's title with the same rules backend uses to compute\n    ``title_folded`` and looks it up here.\n  * ``by_title_match`` \u2014 ``{match_key: canonical_track_id}``. Like\n    ``by_title_folded`` but with trailing source annotations removed\n    (\"(Live)\", \"- 2011 Remaster\", \"(feat. \u2026)\"), which is what a\n    Deezer tracklist carries and a Plex file tag usually does not.\n    Keys claimed by two canonicals are dropped rather than guessed \u2014\n    see :func:`api.canonical.match_key.build_match_map`.\n  * ``by_position`` \u2014 ``{\"<disc>::<track>\": canonical_track_id}``.\n    Last-ditch fallback for manually-linked Plex tracks whose\n    merged title diverges from Deezer's (Plex pulls titles from\n    the audio file's tag, which often differs in capitalisation,\n    bracketed annotations, etc.). On an album, disc + track number\n    uniquely identify a song \u2014 so if the canonical and the Deezer\n    row agree on those, that's a confident match. Disc defaults\n    to 1 when missing (single-disc albums never set the field).\n\nSingle indexed query for all three maps; the SPA picks whichever\nkey resolves per row.",
        "operationId": "list_plex_playable_tracks_plex_play_album_tracks__canonical_album_id__get",
        "parameters": [
          {
            "name": "canonical_album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "title": "Response List Plex Playable Tracks Plex Play Album Tracks  Canonical Album Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/album/{canonical_album_id}/cover": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Get Album Cover",
        "description": "Stream a Plex-album's thumb so the SPA can render it directly.\n\nPlex stores album thumbs at ``/library/metadata/<ratingKey>/thumb``\nbehind a token-authenticated GET. The path is relative to the Plex\nserver's host:port and never directly usable from a browser. The\nalbum merger therefore omits Plex thumbs from the canonical's\n``cover_url`` field \u2014 but for libraries where Plex is the only\nsource, that leaves the SPA cover-less.\n\nThis proxy fills the gap: SPA hits ``/plex/album/<canonical_id>\n/cover`` whenever ``track.album.cover_url`` is null and\n``track.album.sources.plex`` is true. We resolve the canonical\nalbum \u2192 Plex external_ref \u2192 ratingKey, then stream the bytes\nback. Admin token is fine (same auth model as the audio + playlist\nproxies); per-user token isn't needed for thumb reads.\n\n404 when the album isn't Plex-linked; 503 if the server isn't\nconfigured. Failures are explicit so the SPA can fall back to a\nplaceholder cleanly.",
        "operationId": "get_album_cover_plex_album__canonical_album_id__cover_get",
        "parameters": [
          {
            "name": "canonical_album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/play/track/{canonical_id}": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Play Plex Track",
        "description": "Direct-play proxy for a canonical track linked to Plex.\n\nReturns the bytes Plex sends back from ``/library/parts/<partId>``.\nThe original Range header is forwarded so the browser can seek.",
        "operationId": "play_plex_track_plex_play_track__canonical_id__get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/play/track/{canonical_id}/timeline": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Post Timeline",
        "description": "Report playback state for a Plex track on behalf of the user.\n\nThis is how Plex's LastFM scrobbler actually gets triggered.\nThe bytes-only streaming proxy doesn't generate any play state \u2014\nso Plex's server-side LastFM agent (and play history, last\nplayed at, play count) never updates for SPA listens. The\n``/:/scrobble`` toggle bumps playcount but doesn't reliably\ntrigger the LastFM agent; the timeline events real Plex clients\nsend do.\n\nSequence the SPA fires per track:\n\n* On ``playing`` (first audio frame): ``state=playing, time_ms=0``\n* Every ~10 s while playing: ``state=playing, time_ms=current``\n* On ``pause`` / navigation away: ``state=paused, time_ms=current``\n* On ``ended`` or user stop: ``state=stopped, time_ms=current``\n\nPlex's LastFM agent consumes those state transitions exactly the\nway the actual LastFM scrobbler does \u2014 fires when the track was\nplayed >50% or for 4+ minutes, whichever first.\n\nPer-user token required: scrobbles are tied to the Plex account\nthat owns the token, so the server token wouldn't reach the\ncaller's LastFM. 412 if the user hasn't completed the Plex\nOAuth pin flow.\n\nFire-and-forget at the HTTP boundary \u2014 Plex errors are logged\nbut never bubble to the SPA so playback isn't disrupted.",
        "operationId": "post_timeline_plex_play_track__canonical_id__timeline_post",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimelinePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Post Timeline Plex Play Track  Canonical Id  Timeline Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/play/track/{canonical_id}/transcode.mp3": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Transcode Plex Track",
        "description": "Transcode-to-MP3 fallback for direct-play codec compat.\n\nUse when the source is FLAC / OGG / something the browser can't\nplay natively. Plex spins up a transcode session and streams an\nMP3. Seek support depends on Plex's transcoder; in practice it's\nless reliable than direct play, so the SPA only falls here on a\ndirect-play ``error`` event.",
        "operationId": "transcode_plex_track_plex_play_track__canonical_id__transcode_mp3_get",
        "parameters": [
          {
            "name": "canonical_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Canonical Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/server": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Server Info",
        "description": "Live ``/identity`` ping against the global server.\n\nUsed by the admin panel's Server card. Returns the unwrapped\nMediaContainer (``machineIdentifier``, ``friendlyName``,\n``version``, ``platform``, etc.) on success.",
        "operationId": "admin_server_info_plex_admin_server_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Server Info Plex Admin Server Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/stats": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Stats",
        "description": "Aggregate Plex usage stats for the admin panel.\n\n``entities`` is the *active* count (excludes soft-deleted items);\n``entities_deleted`` separately surfaces the tombstoned items so\nadmins can see \"your TV library shrank by N episodes since last\nsync\" at a glance. The historical records remain queryable via the\nper-entity endpoints with ``include_deleted=true``.",
        "operationId": "admin_stats_plex_admin_stats_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Stats Plex Admin Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/non-flac-albums": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Non Flac Albums",
        "description": "Plex albums that aren't fully FLAC \u2014 replace candidates.\n\nAny album with \u22651 non-FLAC track, worst-affected first. Each row\nlinks to the canonical album page when one exists. Read-only over the\nlocal Plex mirror (no Plex API calls).",
        "operationId": "admin_non_flac_albums_plex_admin_non_flac_albums_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1000,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Non Flac Albums Plex Admin Non Flac Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/linked-users": {
      "get": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Linked Users",
        "description": "One row per app user who has linked a Plex.tv identity.",
        "operationId": "admin_linked_users_plex_admin_linked_users_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Admin Linked Users Plex Admin Linked Users Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/linked-users/{username}": {
      "delete": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Unlink User",
        "description": "Force-unlink a user (admin override).",
        "operationId": "admin_unlink_user_plex_admin_linked_users__username__delete",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Unlink User Plex Admin Linked Users  Username  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/libraries/refresh": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Refresh Libraries",
        "description": "Re-discover libraries on the global server.",
        "operationId": "admin_refresh_libraries_plex_admin_libraries_refresh_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Admin Refresh Libraries Plex Admin Libraries Refresh Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/libraries/{section_id}/sync": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Sync One",
        "description": "Fire-and-forget per-library sync.\n\nMusic libraries with thousands of tracks routinely exceed the\nSPA's 15s HTTP timeout, so the work runs on the event loop and\nthe SPA polls ``/admin/task-history/{task_id}`` for progress.\n\n``quick=true`` (music only): sync artists + albums fully but fetch\ntracks only for new/changed albums \u2014 seconds on a stable library.",
        "operationId": "admin_sync_one_plex_admin_libraries__section_id__sync_post",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Section Id"
            }
          },
          {
            "name": "quick",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Quick"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Sync One Plex Admin Libraries  Section Id  Sync Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/sync-all": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Sync All",
        "description": "Fire-and-forget version of the cron job.\n\nMulti-library sync across a non-trivial Plex server takes\nminutes. The SPA polls ``/admin/task-history/{task_id}``.\n``quick=true`` forwards to each library (music: new/changed-album\ntracks only).",
        "operationId": "admin_sync_all_plex_admin_sync_all_post",
        "parameters": [
          {
            "name": "quick",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Quick"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Sync All Plex Admin Sync All Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/plex/admin/playlists/sync-all": {
      "post": {
        "tags": [
          "plex"
        ],
        "summary": "Admin Sync All Playlists",
        "description": "Fire-and-forget sync of every linked user's Plex playlists.\n\nDistinct from ``/admin/sync-all`` (which syncs the global library\nvia the admin token). Playlists are per-user, so this iterates\nover every media-user with a stored ``plex_user_token`` and runs\n``sync_user_playlists`` for each. Per-user failures are isolated.",
        "operationId": "admin_sync_all_playlists_plex_admin_playlists_sync_all_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Sync All Playlists Plex Admin Playlists Sync All Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/public/wishlist/albums": {
      "get": {
        "tags": [
          "public"
        ],
        "summary": "Public Wishlist Albums",
        "description": "Every user's wishlisted albums, each with its Deezer website link.\n\nPublic + cross-user. One entry per ``(user, album)`` wishlist row,\nnewest first. ``deezer_url`` is ``null`` when the canonical album\nisn't linked to Deezer; pass ``?deezer_only=true`` to drop those.",
        "operationId": "public_wishlist_albums_public_wishlist_albums_get",
        "parameters": [
          {
            "name": "deezer_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Deezer Only"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Public Wishlist Albums Public Wishlist Albums Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions": {
      "post": {
        "tags": [
          "radio"
        ],
        "summary": "Start Session",
        "description": "Start a radio session seeded by a canonical artist or album.\n\nPicks the first track immediately so the SPA can press play\nwithout a second round-trip. Refuses with **422** when the seed's\ncandidate pool is too thin to make the radio worthwhile\n(cold-start: small library, no scrobble history yet, etc.).",
        "operationId": "start_session_radio_sessions_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartSessionPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Start Session Radio Sessions Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/active": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "Get Active Session",
        "description": "Current user's active session (or ``null`` when none).\n\nPowers app-boot session restoration \u2014 the SPA hits this after\nlogin to decide whether to drop the user back into a radio they\nwere already running.",
        "operationId": "get_active_session_radio_sessions_active_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "additionalProperties": true
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Response Get Active Session Radio Sessions Active Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/recent": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "List Recent Sessions",
        "description": "The user's recent radio sessions (active + ended), newest first.\n\nPowers the \"Recent stations\" list on the idle Radio page: each row\ncan be **resumed** (continue where it left off) or **restarted** (a\nfresh station from the same seed). Declared before\n``/sessions/{session_id}`` so the literal path wins the match.",
        "operationId": "list_recent_sessions_radio_sessions_recent_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Recent Sessions Radio Sessions Recent Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/seed-from-text": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "Radio Seed From Text",
        "description": "Interpret a plain-English listening request into a radio seed.\n\ne.g. *\"something mellow for a rainy Sunday\"* \u2192 ``{seed_kind: \"mood\",\nseed_id: \"melancholy\"}``, ready to POST to ``/radio/sessions``.\n\nGrounded: mood/genre come from **this library's** actual values and\nartist names are resolved against our own canonicals \u2014 the model picks\nintent, never ids. The engine still does all pool building + scoring.\n\nAlways 200 with a ``state`` (``ok`` / ``not_configured`` / ``failed``)\nso the SPA falls back to the manual seed pickers.",
        "operationId": "radio_seed_from_text_radio_seed_from_text_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Q"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Radio Seed From Text Radio Seed From Text Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/moods": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "List Moods",
        "description": "Distinct moods present in the playable library, with track counts.\n\nPowers the mood-mix pickers (the idle Radio page + the ``/moods``\nbrowse page). Scoped to Plex-playable, non-tombstoned tracks so every\nmood listed actually yields a startable pool \u2014 same source filter the\nengine's ``_pool_for_mood_seed`` applies. Sorted by count desc (mood\nname as the tie-break). ``limit`` 0 = all.",
        "operationId": "list_moods_radio_moods_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Limit"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Moods Radio Moods Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/{session_id}": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "Get Session",
        "operationId": "get_session_radio_sessions__session_id__get",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Session Radio Sessions  Session Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "radio"
        ],
        "summary": "End Session",
        "description": "Discard / end a session. Idempotent \u2014 ending an already-ended\nsession is not an error.",
        "operationId": "end_session_radio_sessions__session_id__delete",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response End Session Radio Sessions  Session Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/{session_id}/resume": {
      "post": {
        "tags": [
          "radio"
        ],
        "summary": "Resume Session",
        "description": "Re-open a saved session and continue from where it left off.\n\nCloses any currently-open session (one active per user), clears this\nsession's ``ended_at`` so it becomes the active one, and returns it\nshaped exactly like the active GET. The session's cached candidate\npool is reused, so advancing continues the same station rather than\nre-running the engine (use a fresh ``POST /sessions`` with the same\nseed for that \u2014 the SPA's \"Restart\" action).",
        "operationId": "resume_session_radio_sessions__session_id__resume_post",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Resume Session Radio Sessions  Session Id  Resume Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/{session_id}/advance": {
      "post": {
        "tags": [
          "radio"
        ],
        "summary": "Advance Session",
        "description": "Pick the next track. The SPA calls this on track-end / user-skip.\n\nLogs the previous track's outcome both onto the session (for\nsequencing) and into ``radio_feedback`` (for cross-session\nlearning) when the outcome is a negative signal.",
        "operationId": "advance_session_radio_sessions__session_id__advance_post",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdvancePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Advance Session Radio Sessions  Session Id  Advance Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/sessions/{session_id}/feedback": {
      "post": {
        "tags": [
          "radio"
        ],
        "summary": "Post Feedback",
        "description": "Log a thumb up/down for a track \u2014 a radio *taste* signal only.\n\nThumb-up / thumb-down feed the engine's scoring (loved bonus /\npenalty) and persist in ``radio_feedback`` for cross-session bias.\nThey do NOT touch the favorites collection: favoriting a track is a\ndeliberate, separate action (``POST /me/favorites/tracks``) that the\nplayer exposes as its own button and which has no effect on radio.",
        "operationId": "post_feedback_radio_sessions__session_id__feedback_post",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeedbackPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Post Feedback Radio Sessions  Session Id  Feedback Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/discoveries/summary": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "Discoveries Summary",
        "description": "Lightweight count for the radio-page \"N recommendations\" chip.",
        "operationId": "discoveries_summary_radio_discoveries_summary_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Discoveries Summary Radio Discoveries Summary Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/discoveries": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "List Discoveries",
        "description": "The user's accumulated \"couldn't play these\" recommendations.\n\nRanked by how often the radio wanted to play them (then similarity).\nRows that have since entered the library are flagged ``in_library``\n(and linked to) rather than dropped, so an add is visibly reflected.",
        "operationId": "list_discoveries_radio_discoveries_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Offset"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Discoveries Radio Discoveries Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/radio/discoveries/{discovery_id}/dismiss": {
      "post": {
        "tags": [
          "radio"
        ],
        "summary": "Dismiss Discovery",
        "description": "Hide one discovery. Ownership-guarded; idempotent.",
        "operationId": "dismiss_discovery_radio_discoveries__discovery_id__dismiss_post",
        "parameters": [
          {
            "name": "discovery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Discovery Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Dismiss Discovery Radio Discoveries  Discovery Id  Dismiss Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/scrobble-links/stats": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Stats",
        "operationId": "my_stats_me_scrobble_links_stats_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response My Stats Me Scrobble Links Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/scrobble-links/unlinked": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Unlinked",
        "operationId": "my_unlinked_me_scrobble_links_unlinked_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "artist",
                "album",
                "track"
              ],
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response My Unlinked Me Scrobble Links Unlinked Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/scrobble-links/linked": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Linked",
        "operationId": "my_linked_me_scrobble_links_linked_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "artist",
                "album",
                "track"
              ],
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response My Linked Me Scrobble Links Linked Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/scrobble-links": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Add Link",
        "operationId": "my_add_link_me_scrobble_links_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response My Add Link Me Scrobble Links Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Delete Link",
        "operationId": "my_delete_link_me_scrobble_links_delete",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteLinkQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response My Delete Link Me Scrobble Links Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/scrobble-links/auto-link": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "My Auto Link",
        "description": "Run the auto-linker against the caller's scrobbles right now.\n\n``only_unlinked=True`` (default) is fast; ``False`` re-evaluates\nevery scrobble (useful after canonical priorities change).",
        "operationId": "my_auto_link_me_scrobble_links_auto_link_post",
        "parameters": [
          {
            "name": "only_unlinked",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Only Unlinked"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response My Auto Link Me Scrobble Links Auto Link Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/users": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Users",
        "description": "List every app user with a LastFM connection + their link stats.\n\nThe dashboard renders this as a per-user table with quick links\ninto individual user views.",
        "operationId": "admin_users_admin_scrobble_links_users_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Admin Users Admin Scrobble Links Users Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/{username}/stats": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Stats",
        "operationId": "admin_stats_admin_scrobble_links__username__stats_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Stats Admin Scrobble Links  Username  Stats Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/{username}/unlinked": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Unlinked",
        "operationId": "admin_unlinked_admin_scrobble_links__username__unlinked_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "artist",
                "album",
                "track"
              ],
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Admin Unlinked Admin Scrobble Links  Username  Unlinked Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/{username}/linked": {
      "get": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Linked",
        "operationId": "admin_linked_admin_scrobble_links__username__linked_get",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "artist",
                "album",
                "track"
              ],
              "type": "string",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Admin Linked Admin Scrobble Links  Username  Linked Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/reconcile-all": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Reconcile All",
        "description": "Fire-and-forget version of the nightly auto-link reconciler.\n\nWalking every user's scrobbles can take minutes on heavy\nlisteners \u2014 far past the SPA's HTTP timeout. The work runs on the\nevent loop; the SPA polls ``/admin/task-history/{task_id}``.\n\nIncremental: only touches scrobbles missing at least one\ncanonical_*_id. Cheap. Run nightly.",
        "operationId": "admin_reconcile_all_admin_scrobble_links_reconcile_all_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Reconcile All Admin Scrobble Links Reconcile All Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/relink-artist/{artist_id}": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Relink By Artist",
        "description": "Force-relink every scrobble whose artist matches this canonical's name.\n\nTargeted version of ``relink-all`` for fixing the\n\"scrobbles point at a duplicate canonical\" symptom: when the user\nhas linked all sources to canonical X but some \"Pink Floyd\"\nscrobbles still resolve to canonical Y (a duplicate), this\nendpoint walks every scrobble where ``artist.name`` folds to X's\nname and re-runs ``compute_canonical_ids``. The tiebreaker added\nin 1b ensures the most-sourced canonical wins \u2192 all scrobbles\nconverge on X without manual per-scrobble action.\n\nForce-mode is the only mode: this endpoint *overwrites* existing\n``canonical_artist_id`` on every matching scrobble. That's the\nexplicit user intent \u2014 they're asserting \"X is the right\ncanonical for this name.\" Bounded blast radius: only scrobbles\nwith this folded name are touched.\n\nSynchronous (not background-task'd) because the work is small \u2014\none user's \"Pink Floyd\" scrobbles is at most a few thousand docs,\nnot the millions a full relink-all touches.",
        "operationId": "admin_relink_by_artist_admin_scrobble_links_relink_artist__artist_id__post",
        "parameters": [
          {
            "name": "artist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Relink By Artist Admin Scrobble Links Relink Artist  Artist Id  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/relink-album/{album_id}": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Relink By Album",
        "description": "Repair cross-artist album collisions for a canonical album.\n\nBefore the auto-linker's title-only fallback was removed, a\nscrobble for *artist A*'s album (e.g. The Beatles' \"Let It Be\")\nwith no matching canonical album under A could be stamped with\n*artist B*'s same-titled canonical album (The Replacements' \"Let It\nBe\") via a title-only ``title_folded`` match. The album detail page\nthen surfaced the *wrong* artist's scrobble stats (Path 1 of\n``album_stats`` keys off ``canonical_album_id``).\n\nThis re-runs the now-artist-scoped ``compute_canonical_ids`` over\ntwo sets and overwrites their canonical pointers:\n\n* scrobbles currently pointing here (``canonical_album_id ==\n  album_id``) \u2014 the mis-stamped foreign-artist ones re-resolve to\n  ``None`` (or to their own album) and drop off; the genuine ones\n  stay;\n* scrobbles whose (artist, album) names fold to this canonical's\n  (artist_name, title) \u2014 re-links any that legitimately belong here\n  but were previously missed.\n\nSynchronous: bounded to one album's worth of matching scrobbles.\nThe auto-linker fix prevents *new* mis-stamps; this cleans up the\nones already in the bank vault. Scrobbles are never deleted \u2014 only\ntheir derived canonical pointers are recomputed.",
        "operationId": "admin_relink_by_album_admin_scrobble_links_relink_album__album_id__post",
        "parameters": [
          {
            "name": "album_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Album Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Relink By Album Admin Scrobble Links Relink Album  Album Id  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/relink-all": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Relink All",
        "description": "Full rebuild \u2014 re-evaluates **every** scrobble.\n\nDistinct from ``reconcile-all``: this one re-evaluates already-\nlinked scrobbles too. Use after:\n\n* canonical merges (stale ``canonical_*_id`` should follow to\n  the survivor \u2014 without this, dashboards show \"unlinked\" for\n  scrobbles that point at tombstones)\n* a Plex / MB enrichment that minted new canonicals and you want\n  old scrobbles to pick them up even though they were already\n  linked at the artist level\n* any priority-table or projector change that would have produced\n  different links if it had been in place at ingest time\n\nSlower than reconcile-all because it walks every scrobble, not\njust unlinked ones. Still fire-and-forget; the SPA polls\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_relink_all_admin_scrobble_links_relink_all_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Relink All Admin Scrobble Links Relink All Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/{username}": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Add Link",
        "operationId": "admin_add_link_admin_scrobble_links__username__post",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Add Link Admin Scrobble Links  Username  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Delete Link",
        "operationId": "admin_delete_link_admin_scrobble_links__username__delete",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteLinkQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Delete Link Admin Scrobble Links  Username  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/scrobble-links/{username}/auto-link": {
      "post": {
        "tags": [
          "scrobble-links"
        ],
        "summary": "Admin Auto Link",
        "description": "Fire-and-forget per-user auto-link.\n\nA heavy listener's \"re-link everything\" run easily exceeds the\nSPA's 15s timeout (we walk every scrobble). The SPA polls\n``/admin/task-history/{task_id}``.",
        "operationId": "admin_auto_link_admin_scrobble_links__username__auto_link_post",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "only_unlinked",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Only Unlinked"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Auto Link Admin Scrobble Links  Username  Auto Link Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/search": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Unified Search",
        "description": "Unified canonical+Deezer search with per-row user status.\n\nEmpty ``q`` returns an empty shell \u2014 the SPA renders a \"type to\nsearch\" placeholder for empty inputs, so we never want to do a\nfull-corpus query.\n\n``include_fallback=false`` skips the Deezer/MusicBrainz lookups and\nanswers purely from our own canonicals. Those lookups are the only\nslow part of this endpoint, so callers that don't render them (the\nLibrary page's in-page search consumes the canonical section only)\nshould opt out and get a local-Mongo-speed response.",
        "operationId": "unified_search_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "",
              "title": "Q"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "all",
                "artist",
                "album",
                "track"
              ],
              "type": "string",
              "default": "all",
              "title": "Kind"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "include_fallback",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Include Fallback"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unified Search Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me": {
      "get": {
        "tags": [
          "spotify"
        ],
        "summary": "Get My Spotify Link",
        "description": "Return the caller's Spotify identity, or ``{link: null}`` if\nnot linked.\n\nMirrors the shape of ``GET /plex/me`` so the SPA can use the same\n\"is this service connected?\" pattern.\n\nFetches fresh from Mongo rather than trusting the dependency dict\n\u2014 Spotify access tokens rotate (refresh flow writes back to prefs\non every refresh), so a request-scoped snapshot can lag behind\nreality. The cost is one extra single-doc read per call which is\nnegligible for a per-user endpoint.",
        "operationId": "get_my_spotify_link_spotify_me_get",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get My Spotify Link Spotify Me Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "spotify"
        ],
        "summary": "Unlink Spotify",
        "description": "Drop all Spotify creds + identity from the caller's prefs.\n\nDoesn't revoke on Spotify's side \u2014 that's only possible by the\nuser visiting accounts.spotify.com/apps. The refresh token becomes\ninert as soon as they do; until then we just stop using it.",
        "operationId": "unlink_spotify_spotify_me_delete",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "boolean"
                  },
                  "title": "Response Unlink Spotify Spotify Me Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/auth/start": {
      "post": {
        "tags": [
          "spotify"
        ],
        "summary": "Start Auth",
        "description": "Begin the OAuth flow \u2014 returns the URL the SPA should redirect to.\n\nThe SPA does the actual navigation; we don't 302 directly because\nthat would lose the user's session cookie context (Spotify needs\nto redirect *back* to our origin, where the same cookie is in\nplay).",
        "operationId": "start_auth_spotify_me_auth_start_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  },
                  "title": "Response Start Auth Spotify Me Auth Start Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/auth/callback": {
      "get": {
        "tags": [
          "spotify"
        ],
        "summary": "Auth Callback",
        "description": "OAuth callback \u2014 Spotify redirects here after the user consents.\n\nThree possible shapes:\n  * ``?code=...&state=...`` \u2014 success path; exchange and persist.\n  * ``?error=...`` \u2014 user clicked Cancel on Spotify's consent\n    screen, or Spotify rejected the request. Redirect with the\n    reason so the Settings view can show a meaningful message.\n  * Missing everything \u2014 someone hit the URL directly. 400.\n\nOn any failure we redirect to the SPA's Settings page with a\n``spotify=error&reason=...`` query so the user sees the failure\non the same page they started the flow.",
        "operationId": "auth_callback_spotify_auth_callback_get",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Code"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "State"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Error"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/sync": {
      "post": {
        "tags": [
          "spotify"
        ],
        "summary": "Sync My Library",
        "description": "Kick off a Spotify library + playlists + recently-played sync.\n\nFire-and-forget: returns a ``task_id`` immediately so the SPA's\nHTTP client doesn't time out while the sync walks pages of saved\ntracks / albums / followed-artists / playlists. The SPA polls\n``GET /admin/task-history/{task_id}`` (or uses the\n``useBackgroundTask`` composable) to surface progress + the\nfinal summary.\n\nSync time is roughly linear in (saved-tracks + \u03a3 playlist tracks),\nplus one /me/player/recently-played call. A typical user with ~1k\nsaved tracks + 30 playlists lands in 30\u201360 seconds \u2014 well past\nthe SPA's 15s axios timeout, hence the background-task shape.\n\n412 if the user hasn't linked Spotify.",
        "operationId": "sync_my_library_spotify_me_sync_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Sync My Library Spotify Me Sync Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/playlists/{spotify_playlist_id}/plex-coverage": {
      "get": {
        "tags": [
          "spotify"
        ],
        "summary": "Get Playlist Plex Coverage",
        "description": "Report how many tracks in a Spotify playlist resolve to Plex.\n\nUsed by the SPA's \"preview before sync\" UI: before turning a\nSpotify playlist into a Plex playlist, the user sees ``X of Y\ntracks have a Plex match; Z are Spotify-only``. Doesn't touch\nPlex \u2014 everything resolves from local refs.\n\nThe special id ``__liked_songs__`` reports against the user's\nSpotify Liked Songs (which lives in ``spotify_saved_tracks``,\nnot ``spotify_playlists``).",
        "operationId": "get_playlist_plex_coverage_spotify_me_playlists__spotify_playlist_id__plex_coverage_get",
        "parameters": [
          {
            "name": "spotify_playlist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Spotify Playlist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Playlist Plex Coverage Spotify Me Playlists  Spotify Playlist Id  Plex Coverage Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/playlists": {
      "get": {
        "tags": [
          "spotify"
        ],
        "summary": "List My Playlists",
        "description": "List the caller's Spotify playlists from the local mirror.\n\n``owned_only=True`` (default) hides playlists the user follows\nbut didn't create \u2014 matches Settings's default. Pass\n``owned_only=false`` to include followed playlists.\n\nReads from ``spotify_playlists`` only; doesn't call Spotify. Run\n``POST /spotify/me/sync`` first to populate the mirror.",
        "operationId": "list_my_playlists_spotify_me_playlists_get",
        "parameters": [
          {
            "name": "owned_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Owned Only"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List My Playlists Spotify Me Playlists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/playlists/{spotify_playlist_id}": {
      "get": {
        "tags": [
          "spotify"
        ],
        "summary": "Get My Playlist",
        "description": "Get a single Spotify playlist with its embedded items.\n\nItems carry ``canonical_track_id`` when our sync resolved them\nagainst an existing canonical. Resolution happens at sync time\n\u2014 calling this endpoint never triggers a Spotify network call.",
        "operationId": "get_my_playlist_spotify_me_playlists__spotify_playlist_id__get",
        "parameters": [
          {
            "name": "spotify_playlist_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Spotify Playlist Id"
            }
          },
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get My Playlist Spotify Me Playlists  Spotify Playlist Id  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spotify/me/import-favorites": {
      "post": {
        "tags": [
          "spotify"
        ],
        "summary": "Import Liked Songs To Favorites",
        "description": "One-shot: import the caller's Spotify Liked Songs into\ncanonical favorites.\n\nWalks ``spotify_saved_tracks`` and upserts each row with a\nresolved canonical onto ``media_favorites``. Idempotent \u2014\nalready-favorited tracks count separately in the summary so the\nSPA can render \"imported 12 new; 35 already favorited\".\n\nPrerequisite: a Spotify sync must have run already (so saved\ntracks exist in the mirror with canonical_id stamped). If the\nuser has just linked Spotify but hasn't synced yet, they get\n``candidates: 0`` and nothing happens \u2014 the SPA should suggest\n\"click Sync first\".",
        "operationId": "import_liked_songs_to_favorites_spotify_me_import_favorites_post",
        "parameters": [
          {
            "name": "media_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Media Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Import Liked Songs To Favorites Spotify Me Import Favorites Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/tautulli": {
      "post": {
        "tags": [
          "tautulli"
        ],
        "summary": "Tautulli Webhook",
        "description": "Receive one Tautulli playback event and append it to the log.\n\nThe body is Tautulli's user-defined payload; we store it verbatim under\n``raw`` and lift a normalized projection (see\n:class:`api.tautulli.catalog.TautulliEvents`). Music events get a\nbest-effort canonical link. Always 200 with the stored id \u2014 a payload\nwe can't fully parse is stored, not refused.",
        "operationId": "tautulli_webhook_webhooks_tautulli_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Tautulli Webhook Webhooks Tautulli Post"
                }
              }
            }
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/": {
      "get": {
        "summary": "Root",
        "operationId": "root__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/health/": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health",
        "operationId": "health_health__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/wikipedia/search/": {
      "get": {
        "summary": "Search",
        "operationId": "search_wikipedia_search__get",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Term"
            }
          },
          {
            "name": "save_pages",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Save Pages"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/wikipedia/page/": {
      "get": {
        "summary": "Get Page",
        "operationId": "get_page_wikipedia_page__get",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Page"
            }
          },
          {
            "name": "save",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Save"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AdminPasswordResetPayload": {
        "properties": {
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password"
          }
        },
        "type": "object",
        "required": [
          "new_password"
        ],
        "title": "AdminPasswordResetPayload"
      },
      "AdvancePayload": {
        "properties": {
          "previous_outcome": {
            "enum": [
              "completed",
              "skipped",
              "skip_early",
              "thumb_down",
              "unplayable",
              null
            ],
            "title": "Previous Outcome"
          }
        },
        "type": "object",
        "title": "AdvancePayload"
      },
      "AlbumStatusPayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          },
          "album": {
            "type": "string",
            "minLength": 1,
            "title": "Album"
          }
        },
        "type": "object",
        "required": [
          "artist",
          "album"
        ],
        "title": "AlbumStatusPayload"
      },
      "AskPayload": {
        "properties": {
          "question": {
            "type": "string",
            "title": "Question"
          },
          "conversation_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Conversation Id"
          },
          "entity_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity Ref"
          }
        },
        "type": "object",
        "required": [
          "question"
        ],
        "title": "AskPayload"
      },
      "AskWishlistPayload": {
        "properties": {
          "deezer_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deezer Id"
          },
          "mbid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mbid"
          }
        },
        "type": "object",
        "title": "AskWishlistPayload",
        "description": "A verified discovery suggestion. Exactly one identifier is used."
      },
      "BrowserUrl": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url"
          }
        },
        "type": "object",
        "required": [
          "url"
        ],
        "title": "BrowserUrl"
      },
      "BulkImportPayload": {
        "properties": {
          "from_ts": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Ts"
          },
          "to_ts": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "To Ts"
          }
        },
        "type": "object",
        "title": "BulkImportPayload"
      },
      "CommentBody": {
        "properties": {
          "body": {
            "type": "string",
            "maxLength": 5000,
            "minLength": 1,
            "title": "Body"
          }
        },
        "type": "object",
        "required": [
          "body"
        ],
        "title": "CommentBody"
      },
      "CommentCountsRequest": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/CommentRef"
            },
            "type": "array",
            "maxItems": 500,
            "title": "Items"
          }
        },
        "type": "object",
        "title": "CommentCountsRequest"
      },
      "CommentRef": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "artist",
              "album",
              "track"
            ],
            "title": "Kind"
          },
          "canonical_id": {
            "type": "string",
            "title": "Canonical Id"
          }
        },
        "type": "object",
        "required": [
          "kind",
          "canonical_id"
        ],
        "title": "CommentRef"
      },
      "CreateUserPayload": {
        "properties": {
          "username": {
            "type": "string",
            "maxLength": 64,
            "minLength": 1,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "title": "Password"
          },
          "role": {
            "type": "string",
            "title": "Role",
            "default": "viewer"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "CreateUserPayload"
      },
      "DeleteLinkQuery": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "artist",
              "album",
              "track"
            ],
            "title": "Kind"
          },
          "artist_name": {
            "type": "string",
            "title": "Artist Name"
          },
          "album_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Album Name"
          },
          "track_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Track Name"
          }
        },
        "type": "object",
        "required": [
          "kind",
          "artist_name"
        ],
        "title": "DeleteLinkQuery"
      },
      "EntityRef": {
        "properties": {
          "canonical_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canonical Id"
          },
          "deezer_id": {
            "anyOf": [
              {
                "type": "integer",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Deezer Id"
          }
        },
        "type": "object",
        "title": "EntityRef",
        "description": "Identifies one entity by either internal ULID or a Deezer ID.\n\nExactly one must be set. Future sources slot in as siblings\n(``mbid``, ``spotify_id``, ...) the same way."
      },
      "FavoriteAlbumPayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          },
          "album": {
            "type": "string",
            "minLength": 1,
            "title": "Album"
          }
        },
        "type": "object",
        "required": [
          "artist",
          "album"
        ],
        "title": "FavoriteAlbumPayload"
      },
      "FavoriteArtistPayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          }
        },
        "type": "object",
        "required": [
          "artist"
        ],
        "title": "FavoriteArtistPayload"
      },
      "FavoriteTrackPayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          },
          "track": {
            "type": "string",
            "minLength": 1,
            "title": "Track"
          }
        },
        "type": "object",
        "required": [
          "artist",
          "track"
        ],
        "title": "FavoriteTrackPayload"
      },
      "FeedbackPayload": {
        "properties": {
          "canonical_track_id": {
            "type": "string",
            "title": "Canonical Track Id"
          },
          "signal": {
            "type": "string",
            "enum": [
              "thumb_up",
              "thumb_down"
            ],
            "title": "Signal"
          }
        },
        "type": "object",
        "required": [
          "canonical_track_id",
          "signal"
        ],
        "title": "FeedbackPayload"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "LinkPayload": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "artist",
              "album",
              "track"
            ],
            "title": "Kind"
          },
          "artist_name": {
            "type": "string",
            "minLength": 1,
            "title": "Artist Name"
          },
          "album_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Album Name"
          },
          "track_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Track Name"
          },
          "canonical_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canonical Id"
          },
          "unmatchable": {
            "type": "boolean",
            "title": "Unmatchable",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "kind",
          "artist_name"
        ],
        "title": "LinkPayload",
        "description": "Body for ``POST /me/scrobble-links`` and admin equivalent.\n\n``kind`` + name fields identify which scrobble group is being\nlinked. Exactly one of ``canonical_id`` and ``unmatchable`` must\nbe set: a real link or an explicit \"no match\" decision."
      },
      "LinkSourcePayload": {
        "properties": {
          "source": {
            "type": "string",
            "title": "Source"
          },
          "external_id": {
            "type": "string",
            "title": "External Id"
          }
        },
        "type": "object",
        "required": [
          "source",
          "external_id"
        ],
        "title": "LinkSourcePayload",
        "description": "Body for ``POST /{kind}s/{id}/refs`` \u2014 attach a source ref.\n\n``source`` is one of ``deezer``, ``musicbrainz``, ``plex``,\n``lastfm``, ``itunes``. ``external_id`` is whatever the matching\nsource uses:\n\n* deezer: numeric ID as a string (e.g. ``\"302127\"``)\n* musicbrainz: release-group / artist / recording MBID\n* plex: compound ``\"<machine_id>::<rating_key>\"``\n* lastfm: lowercased ``<artist>`` or ``<artist>::<title>``\n* itunes: Apple numeric id (artistId / collectionId / trackId)"
      },
      "LoginPayload": {
        "properties": {
          "username": {
            "type": "string",
            "minLength": 1,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 1,
            "title": "Password"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "LoginPayload"
      },
      "LoveTrackPayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          },
          "track": {
            "type": "string",
            "minLength": 1,
            "title": "Track"
          }
        },
        "type": "object",
        "required": [
          "artist",
          "track"
        ],
        "title": "LoveTrackPayload"
      },
      "MergePayload": {
        "properties": {
          "source_id": {
            "type": "string",
            "title": "Source Id"
          }
        },
        "type": "object",
        "required": [
          "source_id"
        ],
        "title": "MergePayload",
        "description": "Body for the merge endpoints \u2014 names the *loser* canonical.\n\nThe URL path identifies the *target* (survivor); the body picks\nthe source (loser). Refs, user-data and cross-entity pointers all\nmove from source \u2192 target."
      },
      "PasswordChangePayload": {
        "properties": {
          "current_password": {
            "type": "string",
            "minLength": 1,
            "title": "Current Password"
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password"
          }
        },
        "type": "object",
        "required": [
          "current_password",
          "new_password"
        ],
        "title": "PasswordChangePayload"
      },
      "PreferencesPatch": {
        "properties": {
          "preferences": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preferences"
          }
        },
        "type": "object",
        "title": "PreferencesPatch"
      },
      "ProvisionHomeUserPayload": {
        "properties": {
          "new_username": {
            "type": "string",
            "maxLength": 32,
            "minLength": 3,
            "title": "New Username"
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password"
          },
          "pin": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 8
              },
              {
                "type": "null"
              }
            ],
            "title": "Pin"
          }
        },
        "type": "object",
        "required": [
          "new_username",
          "new_password"
        ],
        "title": "ProvisionHomeUserPayload",
        "description": "Body for ``POST /plex/me/home-users/{id}/provision``.\n\n``new_username`` + ``new_password`` follow the same rules as\n``/auth/register`` so the provisioned account is indistinguishable\nfrom a self-registered one. ``pin`` is optional \u2014 required only\nwhen plex.tv reports ``protected=True`` for this Home user."
      },
      "PurgePayload": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "all",
              "pre2000",
              "future"
            ],
            "title": "Kind"
          }
        },
        "type": "object",
        "required": [
          "kind"
        ],
        "title": "PurgePayload"
      },
      "RefsCheckPayload": {
        "properties": {
          "source": {
            "type": "string",
            "title": "Source"
          },
          "external_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "External Ids"
          }
        },
        "type": "object",
        "required": [
          "source",
          "external_ids"
        ],
        "title": "RefsCheckPayload",
        "description": "Body for the picker's batch-check.\n\n``external_ids`` may contain whatever the picker's source returned \u2014\nwe ``$in`` lookup against the corresponding refs collection."
      },
      "RegisterPayload": {
        "properties": {
          "username": {
            "type": "string",
            "maxLength": 32,
            "minLength": 3,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "title": "Password"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "RegisterPayload",
        "description": "Self-registration payload \u2014 always lands as a ``viewer``."
      },
      "ScrobbleCanonicalStampPayload": {
        "properties": {
          "canonical_artist_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canonical Artist Id"
          },
          "canonical_album_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canonical Album Id"
          },
          "canonical_track_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canonical Track Id"
          }
        },
        "type": "object",
        "title": "ScrobbleCanonicalStampPayload",
        "description": "Stamp body for ``POST /me/scrobbles/{id}/canonical-link``.\n\nAny subset of the three fields may be supplied \u2014 endpoints\ntypically have one of them at a time (the dashboard click handler\nknows the track-level resolution but not always the album/artist\nparents). Unset fields are not touched on the scrobble."
      },
      "ScrobblePayload": {
        "properties": {
          "artist": {
            "type": "string",
            "minLength": 1,
            "title": "Artist"
          },
          "track": {
            "type": "string",
            "minLength": 1,
            "title": "Track"
          },
          "album": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Album"
          },
          "timestamp": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timestamp"
          }
        },
        "type": "object",
        "required": [
          "artist",
          "track"
        ],
        "title": "ScrobblePayload"
      },
      "StartSessionPayload": {
        "properties": {
          "seed_kind": {
            "type": "string",
            "enum": [
              "artist",
              "album",
              "track",
              "mood",
              "artist_deep",
              "genre"
            ],
            "title": "Seed Kind",
            "description": "Kind of seed the radio is built from. Album seeds heavily weight the seeded album's own tracks for the first several picks. Track seeds open with the exact seeded track, then drift through LastFM-similar tracks before falling back to the seed artist's related-artists pool. Mood seeds pull every library track tagged with the mood. ``artist_deep`` is the 'deep cuts' station: ONLY the seed artist's tracks, favouring ones you've never played and excluding your thumb-downs."
          },
          "seed_id": {
            "type": "string",
            "title": "Seed Id",
            "description": "Canonical entity ID (ULID) for artist/album/track seeds, or the mood string itself for mood seeds."
          }
        },
        "type": "object",
        "required": [
          "seed_kind",
          "seed_id"
        ],
        "title": "StartSessionPayload"
      },
      "TimelinePayload": {
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "playing",
              "paused",
              "stopped"
            ],
            "title": "State"
          },
          "time_ms": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Time Ms",
            "description": "Current playback position in ms."
          },
          "duration_ms": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Duration Ms",
            "description": "Total track duration in ms. Optional but strongly recommended \u2014 Plex's LastFM agent uses this to compute the >50% scrobble threshold."
          }
        },
        "type": "object",
        "required": [
          "state",
          "time_ms"
        ],
        "title": "TimelinePayload",
        "description": "Body shape for ``POST /plex/play/track/{id}/timeline``."
      },
      "UpdateUserPayload": {
        "properties": {
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role"
          }
        },
        "type": "object",
        "title": "UpdateUserPayload"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    },
    "securitySchemes": {
      "APIKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "api-key"
      },
      "APIKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-tautulli-token"
      }
    }
  }
}
