<!-- Generated by `just docs` from catalog/toolkits/spotify.yaml, catalog/expansions/spotify.yaml, catalog/evals/scorecard.json. Edit the source, not this file. -->

# Spotify

Music streaming. Search the catalog, control playback on a device, manage playlists, save tracks and albums, and read history.

| Property | Value |
| --- | --- |
| Slug | `spotify` |
| Definition version | `0.1.0` |
| Base URL | `https://api.spotify.com/v1` |
| Auth schemes | `oauth2` |
| Action tools | 40 |
| By class | 18 read, 17 write, 5 destructive |
| Triggers | 0 |
| Provider rate limit | not declared, so outbound calls are unpaced |

## Measured routing accuracy

58 golden cases replayed through the router over the whole index: measured over corpus `ea4f12ad2948` (65 toolkits, 2283 tools indexed and 13 declared uncallable), 40 cases written by hand and 18 cases from the paraphrase pass. A case counts as top-1 when its gold tool ranked first and top-8 when it reached the slate at all.

| Measure | Cases | Share |
| --- | --- | --- |
| top-1 | 25/58 | 43.1% |
| top-8 | 47/58 | 81.0% |

The sweep is offline: the reranker is a deterministic identity fake that returns candidates in the order retrieval produced them, so top-1 measures retrieval order rather than a reranked slate. `just eval-live` measures the same cases through the live reranker.

## Authentication

Connect an entity with `ConnectionsService.InitiateConnection`, naming this toolkit's slug. Credentials stay in the connections vault; callers hold connected-account ids only.

### `oauth2`

| Property | Value |
| --- | --- |
| Authorization URL | `https://accounts.spotify.com/authorize` |
| Token URL | `https://accounts.spotify.com/api/token` |
| Default scopes | `user-read-playback-state`, `user-modify-playback-state`, `user-read-email`, `user-read-private`, `playlist-read-private`, `playlist-modify-public`, `playlist-modify-private`, `user-library-read`, `user-library-modify`, `user-top-read`, `user-read-recently-played`, `user-follow-read`, `user-follow-modify` |
| Refresh tokens | yes, the refresh daemon renews ahead of expiry |

## Tools

40 action tools. The catalog-wide slug is `spotify.<tool>`, which is what `search_tools` returns and `call_tool` takes.

### `spotify.search`

Search the Spotify catalog for tracks, albums, artists, or playlists by keyword. Use when the user wants to find or play something by name and you don't already have its Spotify id. For an id you already have, use get_track, get_album, or get_artist instead.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /search`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `limit` | integer | no | Maximum results per type, up to 50. Default 20. |
| `market` | string | no | ISO 3166-1 alpha-2 country code narrowing results to what's playable there, e.g. "US". |
| `offset` | integer | no | Pagination offset per type. Default 0. |
| `query` | string | **yes** | Search text, e.g. "Blinding Lights The Weeknd". Supports field filters like artist: and album:. |
| `types` | string | **yes** | Comma-separated item types to search, from track, album, artist, playlist, e.g. "track,artist". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `albums` | object |  |
| `albums.items` | array of object |  |
| `albums.items[].artists` | array of object |  |
| `albums.items[].external_urls` | object |  |
| `albums.items[].id` | string |  |
| `albums.items[].name` | string |  |
| `albums.items[].release_date` | string |  |
| `artists` | object |  |
| `artists.items` | array of object |  |
| `artists.items[].external_urls` | object |  |
| `artists.items[].genres` | array of string |  |
| `artists.items[].id` | string |  |
| `artists.items[].name` | string |  |
| `artists.items[].popularity` | integer |  |
| `playlists` | object |  |
| `playlists.items` | array of object |  |
| `playlists.items[].external_urls` | object |  |
| `playlists.items[].id` | string |  |
| `playlists.items[].name` | string |  |
| `playlists.items[].owner` | object |  |
| `playlists.items[].tracks` | object |  |
| `tracks` | object |  |
| `tracks.items` | array of object |  |
| `tracks.items[].album` | object |  |
| `tracks.items[].artists` | array of object |  |
| `tracks.items[].duration_ms` | integer |  |
| `tracks.items[].external_urls` | object |  |
| `tracks.items[].id` | string |  |
| `tracks.items[].name` | string |  |

Also retrieved by: "look up a song by name", "find that artist on spotify", "hunt down an album title", "see if a playlist exists", "pull up something by keyword".

### `spotify.get_track`

Get full details for one track by its Spotify id: title, artists, album, duration, and popularity. Use when the user already names or links a specific track. To find a track's id from a name, use search first.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /tracks/{{params.track_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `track_id` | string | **yes** | Spotify track id, e.g. "11dFghVXANMlKmJXsNCbNl". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `album` | object |  |
| `album.id` | string |  |
| `album.name` | string |  |
| `album.release_date` | string |  |
| `artists` | array of object |  |
| `artists[].id` | string |  |
| `artists[].name` | string |  |
| `duration_ms` | integer |  |
| `explicit` | boolean |  |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `id` | string |  |
| `name` | string |  |
| `popularity` | integer |  |

Also retrieved by: "what song is this exactly", "details on this specific song", "how long does this song run", "who made this particular song".

### `spotify.get_album`

Get full details for one album by its Spotify id: title, artists, release date, and track count. Use when the user already names or links a specific album. For the album's individual tracks, use get_album_tracks.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /albums/{{params.album_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `album_id` | string | **yes** | Spotify album id, e.g. "4aawyAB9vmqN3uQ7FjRGTy". |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `artists` | array of object |  |
| `artists[].id` | string |  |
| `artists[].name` | string |  |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `id` | string |  |
| `images` | array of object |  |
| `images[].url` | string |  |
| `name` | string |  |
| `release_date` | string |  |
| `total_tracks` | integer |  |

Also retrieved by: "when did this record come out", "how many songs are on this record", "info about this specific release".

### `spotify.get_album_tracks`

List the tracks on an album, in album order. Use when the user asks what songs are on an album or wants its full tracklist. For the album's own title and release details rather than its songs, use get_album.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /albums/{{params.album_id}}/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `album_id` | string | **yes** | Spotify album id, e.g. "4aawyAB9vmqN3uQ7FjRGTy". |
| `limit` | integer | no | Maximum results per page, up to 50. Default 20. |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `offset` | integer | no | Pagination offset. Default 0. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].artists` | array of object |  |
| `items[].artists[].id` | string |  |
| `items[].artists[].name` | string |  |
| `items[].duration_ms` | integer |  |
| `items[].id` | string |  |
| `items[].name` | string |  |
| `items[].track_number` | integer |  |
| `total` | integer |  |

Also retrieved by: "what songs are on this record", "see the full tracklist", "list every song on this release", "what's the order of songs here".

### `spotify.get_artist`

Get full details for one artist by their Spotify id: name, genres, popularity, and follower count. Use when the user already names or links a specific artist. For their most popular songs, use get_artist_top_tracks.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /artists/{{params.artist_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `artist_id` | string | **yes** | Spotify artist id, e.g. "0TnOYISbd1XYRBk9myaseg". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `followers` | object |  |
| `followers.total` | integer |  |
| `genres` | array of string |  |
| `id` | string |  |
| `images` | array of object |  |
| `images[].url` | string |  |
| `name` | string |  |
| `popularity` | integer |  |

Also retrieved by: "who is this musician", "how popular is this act", "what genre does this act play", "how many people follow this musician".

### `spotify.get_artist_top_tracks`

Get an artist's most popular tracks. Use when the user asks for an artist's biggest songs, hits, or best-known tracks. For their whole discography or a specific album, use get_album or get_album_tracks instead.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /artists/{{params.artist_id}}/top-tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `artist_id` | string | **yes** | Spotify artist id, e.g. "0TnOYISbd1XYRBk9myaseg". |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `tracks` | array of object |  |
| `tracks[].album` | object |  |
| `tracks[].album.id` | string |  |
| `tracks[].album.name` | string |  |
| `tracks[].duration_ms` | integer |  |
| `tracks[].external_urls` | object |  |
| `tracks[].external_urls.spotify` | string |  |
| `tracks[].id` | string |  |
| `tracks[].name` | string |  |
| `tracks[].popularity` | integer |  |

Also retrieved by: "this act's biggest hits", "most popular songs by this musician", "what should I listen to first from them", "their most streamed songs".

### `spotify.get_playback_state`

Get what's currently playing and the full player state: device, progress, shuffle, and repeat. Use when the user asks what's playing, what song this is, or which device is active. Returns no item when nothing is playing.

Class `read` (reads only). Scopes `user-read-playback-state`. Calls `GET /me/player`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `device` | object |  |
| `device.id` | string |  |
| `device.name` | string |  |
| `device.type` | string |  |
| `device.volume_percent` | integer |  |
| `is_playing` | boolean |  |
| `item` | object |  |
| `item.album` | object |  |
| `item.album.name` | string |  |
| `item.artists` | array of object |  |
| `item.artists[].name` | string |  |
| `item.duration_ms` | integer |  |
| `item.id` | string |  |
| `item.name` | string |  |
| `progress_ms` | integer |  |
| `repeat_state` | string |  |
| `shuffle_state` | boolean |  |

Also retrieved by: "what's on right now", "which speaker is this playing on", "is anything playing at the moment", "what song is this that's on".

### `spotify.start_playback`

Start or resume playback of a track, album, artist, or playlist. Use when the user wants to play, resume, or start something. Pass context_uri for an album, playlist, or artist, or track_uris for specific tracks. With neither, resumes whatever was paused.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/play`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `context_uri` | string | no | Spotify URI of an album, playlist, or artist to play, e.g. "spotify:album:4aawyAB9vmqN3uQ7FjRGTy". |
| `device_id` | string | no | Device to play on, from get_available_devices. Defaults to the currently active device. |
| `position_ms` | integer | no | Position in the first track to start from, in milliseconds. |
| `track_uris` | array of string | no | Specific track URIs to play instead of a context, e.g. ["spotify:track:11dFghVXANMlKmJXsNCbNl"]. |

Also retrieved by: "hit play on this record", "throw this playlist on", "get this song going", "kick off this album", "put this on".

### `spotify.pause_playback`

Pause playback on the active or a given device. Use when the user wants to pause, stop, or halt what's playing. To resume, use start_playback.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/pause`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to pause. Defaults to the currently active device. |

Also retrieved by: "hold the music for a second", "cut the music", "silence whatever's on".

### `spotify.skip_to_next`

Skip to the next track in the current context. Use when the user wants to skip, go to the next song, or move forward a track. For the previous track, use skip_to_previous.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `POST /me/player/next`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |

Also retrieved by: "next song please", "move on from this one", "I'm done with this track", "forward one song".

### `spotify.skip_to_previous`

Go back to the previous track. Use when the user wants to go back, replay the last song, or skip backward. For the next track, use skip_to_next.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `POST /me/player/previous`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |

Also retrieved by: "go back a song", "that last one again", "rewind to the one before this".

### `spotify.seek_to_position`

Jump to a specific position within the currently playing track. Use when the user wants to skip ahead, rewind, or jump to a point in the current song.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/seek`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |
| `position_ms` | integer | **yes** | Position to seek to, in milliseconds from the start of the track. |

Also retrieved by: "jump ahead in the song", "go back to the chorus", "fast forward this track", "start this over from a point".

### `spotify.set_repeat_mode`

Set the repeat mode for playback. Use when the user wants to repeat the current track, repeat the whole playlist or album, or turn repeat off.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/repeat`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |
| `state` | string, one of track, context, off | **yes** | "track" repeats the current song, "context" repeats the playlist or album, "off" turns repeat off. |

Also retrieved by: "loop this song", "keep this album going in a loop", "stop looping the music", "play this on repeat".

### `spotify.set_playback_volume`

Set the playback volume on the active or a given device. Use when the user wants to turn the volume up, down, or set it to a specific level.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/volume`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |
| `volume_percent` | integer | **yes** | Target volume, 0 to 100. |

Also retrieved by: "turn it up", "lower the sound a bit", "make the music louder", "crank it down".

### `spotify.set_shuffle_mode`

Turn shuffle on or off for playback. Use when the user wants to shuffle, randomize, or turn off shuffling of the current context.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player/shuffle`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |
| `state` | boolean | **yes** | true to shuffle, false to play in order. |

Also retrieved by: "randomize the order", "mix these songs up", "stop playing in order", "shake up the playlist order".

### `spotify.transfer_playback`

Move playback to a different device, like a phone, speaker, or computer. Use when the user wants to switch playback to another device or keep listening somewhere else. Find device ids with get_available_devices.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `PUT /me/player`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | **yes** | Device to transfer playback to, from get_available_devices. |
| `play` | boolean | no | Start playing immediately on the new device. Default keeps the current play or pause state. |

Also retrieved by: "move the music to my speaker", "play this on the living room speaker instead", "switch what's playing over to my phone", "send the audio to another device".

### `spotify.get_available_devices`

List the devices currently available for playback, like phones, speakers, and computers signed into Spotify. Use when the user asks what devices are available, or before calling transfer_playback.

Class `read` (reads only). Scopes `user-read-playback-state`. Calls `GET /me/player/devices`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `devices` | array of object |  |
| `devices[].id` | string |  |
| `devices[].is_active` | boolean |  |
| `devices[].name` | string |  |
| `devices[].type` | string |  |
| `devices[].volume_percent` | integer |  |

Also retrieved by: "what can I play music on right now", "which speakers are online", "see what's signed into my account".

### `spotify.add_to_queue`

Add a track to the end of the playback queue, without interrupting what's playing now. Use when the user wants to queue up, add next, or play something right after the current song.

Class `write` (writes, no confirmation needed). Scopes `user-modify-playback-state`. Calls `POST /me/player/queue`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `device_id` | string | no | Device to act on. Defaults to the currently active device. |
| `track_uri` | string | **yes** | Spotify track URI to queue, e.g. "spotify:track:11dFghVXANMlKmJXsNCbNl". |

Also retrieved by: "play this one right after", "line this up next", "queue this song up".

### `spotify.get_queue`

See the currently playing track and what's queued up to play next. Use when the user asks what's coming up next or what's in the queue.

Class `read` (reads only). Scopes `user-read-playback-state`. Calls `GET /me/player/queue`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `currently_playing` | object |  |
| `currently_playing.artists` | array of object |  |
| `currently_playing.artists[].name` | string |  |
| `currently_playing.id` | string |  |
| `currently_playing.name` | string |  |
| `queue` | array of object |  |
| `queue[].album` | object |  |
| `queue[].album.name` | string |  |
| `queue[].artists` | array of object |  |
| `queue[].artists[].name` | string |  |
| `queue[].id` | string |  |
| `queue[].name` | string |  |

Also retrieved by: "what's coming up after this", "see what's next in line", "what's lined up to play".

### `spotify.get_playlist`

Get details for one playlist by id: name, description, owner, track count, and public or collaborative flags. Use when the user names or links a specific playlist. For the actual tracks inside it, use get_playlist_items.

Class `read` (reads only). Scopes `playlist-read-private`. Calls `GET /playlists/{{params.playlist_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `playlist_id` | string | **yes** | Spotify playlist id, e.g. "37i9dQZF1DXcBWIGoYBM5M". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `collaborative` | boolean |  |
| `description` | string |  |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `followers` | object |  |
| `followers.total` | integer |  |
| `id` | string |  |
| `name` | string |  |
| `owner` | object |  |
| `owner.display_name` | string |  |
| `owner.id` | string |  |
| `public` | boolean |  |
| `tracks` | object |  |
| `tracks.total` | integer |  |

Also retrieved by: "tell me about this collection", "who made this playlist", "how many songs are in this mix".

### `spotify.get_playlist_items`

List the tracks inside a playlist, in playlist order. Use when the user wants to see, read, or browse what's in a playlist. For the playlist's own name and details rather than its contents, use get_playlist.

Class `read` (reads only). Scopes `playlist-read-private`. Calls `GET /playlists/{{params.playlist_id}}/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `limit` | integer | no | Maximum results per page, up to 100. Default 20. |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `offset` | integer | no | Pagination offset. Default 0. |
| `playlist_id` | string | **yes** | Spotify playlist id, e.g. "37i9dQZF1DXcBWIGoYBM5M". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].added_at` | string |  |
| `items[].track` | object |  |
| `items[].track.album` | object |  |
| `items[].track.artists` | array of object |  |
| `items[].track.duration_ms` | integer |  |
| `items[].track.id` | string |  |
| `items[].track.name` | string |  |
| `total` | integer |  |

Also retrieved by: "what songs are in this collection", "show me everything in this mix", "what's inside this playlist".

### `spotify.create_playlist`

Create a new, empty playlist owned by a user. Use when the user wants to make, start, or set up a new playlist. Needs the owning user's id; get it from get_current_user_profile. Add songs afterward with add_items_to_playlist.

Class `write` (writes, no confirmation needed). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `POST /users/{{params.user_id}}/playlists`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `collaborative` | boolean | no | Other users can add or remove tracks. Only valid when public is false. Default false. |
| `description` | string | no | Optional playlist description shown to viewers. |
| `name` | string | **yes** | Playlist name, e.g. "Road Trip 2026". |
| `public` | boolean | no | Visible on the owner's public profile. Default true. |
| `user_id` | string | **yes** | Spotify user id of the owner, from get_current_user_profile. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `description` | string |  |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `id` | string |  |
| `name` | string |  |
| `public` | boolean |  |

Also retrieved by: "start a new collection of songs", "make me a fresh mix", "set up a new song list".

### `spotify.add_items_to_playlist`

Add one or more tracks to a playlist. Use when the user wants to add, put, or include a song in a playlist. Pass Spotify track URIs, e.g. "spotify:track:11dFghVXANMlKmJXsNCbNl". To remove tracks instead, use remove_items_from_playlist.

Class `write` (writes, no confirmation needed). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `POST /playlists/{{params.playlist_id}}/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `playlist_id` | string | **yes** | Spotify playlist id to add tracks to. |
| `position` | integer | no | Zero-based position to insert at. Default appends to the end of the playlist. |
| `track_uris` | array of string | **yes** | Track URIs to add, e.g. ["spotify:track:11dFghVXANMlKmJXsNCbNl"]. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `snapshot_id` | string |  |

Also retrieved by: "drop this song into my mix", "put this track in that collection", "toss this onto the playlist".

### `spotify.remove_items_from_playlist`

Remove one or more tracks from a playlist. Use when the user wants to remove, delete, or take a song out of a playlist. Removes every occurrence of the track in the playlist. Undoable by adding it back with add_items_to_playlist.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `DELETE /playlists/{{params.playlist_id}}/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `playlist_id` | string | **yes** | Spotify playlist id to remove tracks from. |
| `tracks` | array of object | **yes** | Tracks to remove, each an object with a uri field, e.g. [{"uri": "spotify:track:11dFghVXANMlKmJXsNCbNl"}]. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `snapshot_id` | string |  |

Also retrieved by: "take this song out of the mix", "pull this track from that collection", "I don't want this one in the playlist anymore".

### `spotify.update_playlist_details`

Change a playlist's name, description, or public and collaborative settings. Use when the user wants to rename or edit a playlist's details. Does not touch its tracks; for that use add_items_to_playlist or remove_items_from_playlist.

Class `write` (writes, no confirmation needed). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `PUT /playlists/{{params.playlist_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `collaborative` | boolean | no | Other users can add or remove tracks. |
| `description` | string | no | New playlist description. |
| `name` | string | no | New playlist name. |
| `playlist_id` | string | **yes** | Spotify playlist id to update. |
| `public` | boolean | no | Visible on the owner's public profile. |

Also retrieved by: "give this collection a new name", "change what this mix is called", "edit the blurb on this playlist".

### `spotify.follow_playlist`

Follow a playlist, saving it to the user's own library. Use when the user wants to save, follow, or add someone else's playlist to their library. To save a track or album instead, use save_tracks or save_albums.

Class `write` (writes, no confirmation needed). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `PUT /playlists/{{params.playlist_id}}/followers`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `playlist_id` | string | **yes** | Spotify playlist id to follow. |
| `public` | boolean | no | Show the playlist under the user's public profile. Default true. |

Also retrieved by: "save this mix to my library", "keep this collection in my account", "grab this playlist for myself".

### `spotify.unfollow_playlist`

Unfollow a playlist, removing it from the user's library. Use when the user wants to remove, delete, or take a playlist out of their library. The playlist itself is not deleted for its other followers; follow_playlist reverses this.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `playlist-modify-public`, `playlist-modify-private`. Calls `DELETE /playlists/{{params.playlist_id}}/followers`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `playlist_id` | string | **yes** | Spotify playlist id to unfollow. |

Also retrieved by: "take this collection off my account", "drop this mix from my library", "I don't want this playlist anymore".

### `spotify.get_saved_tracks`

List tracks saved to the user's Liked Songs library, most recently added first. Use when the user asks what songs they've saved, liked, or added to their library. For one or two specific tracks, use check_saved_tracks.

Class `read` (reads only). Scopes `user-library-read`. Calls `GET /me/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `limit` | integer | no | Maximum results per page, up to 50. Default 20. |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `offset` | integer | no | Pagination offset. Default 0. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].added_at` | string |  |
| `items[].track` | object |  |
| `items[].track.album` | object |  |
| `items[].track.artists` | array of object |  |
| `items[].track.duration_ms` | integer |  |
| `items[].track.id` | string |  |
| `items[].track.name` | string |  |
| `total` | integer |  |

Also retrieved by: "what's in my liked songs", "show my saved music", "what have I hearted".

### `spotify.save_tracks`

Save one or more tracks to the user's Liked Songs library. Use when the user wants to like, save, or add a song to their library. Pass track ids comma separated. To remove one, use remove_saved_tracks.

Class `write` (writes, no confirmation needed). Scopes `user-library-modify`. Calls `PUT /me/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `track_ids` | string | **yes** | Comma-separated Spotify track ids, e.g. "11dFghVXANMlKmJXsNCbNl,2takcwOaAZWiXQijPHIx7B". |

Also retrieved by: "heart this song", "add this to my liked songs", "keep this track for later".

### `spotify.remove_saved_tracks`

Remove one or more tracks from the user's Liked Songs library. Use when the user wants to unlike, unsave, or take a song out of their library. Pass track ids comma separated. Undoable with save_tracks.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `user-library-modify`. Calls `DELETE /me/tracks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `track_ids` | string | **yes** | Comma-separated Spotify track ids, e.g. "11dFghVXANMlKmJXsNCbNl,2takcwOaAZWiXQijPHIx7B". |

Also retrieved by: "unheart this song", "take this out of my liked songs", "stop keeping this track".

### `spotify.check_saved_tracks`

Check whether specific tracks are already in the user's Liked Songs library. Use when the user asks if they've already saved or liked a song. Pass track ids comma separated; returns one true or false per id, in the same order.

Class `read` (reads only). Scopes `user-library-read`. Calls `GET /me/tracks/contains`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `track_ids` | string | **yes** | Comma-separated Spotify track ids to check. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `saved` | array of boolean |  |

Also retrieved by: "did I already like this one", "is this already in my library", "have I saved this before".

### `spotify.get_saved_albums`

List albums saved to the user's library, most recently added first. Use when the user asks what albums they've saved or added to their library. For individual saved songs rather than whole albums, use get_saved_tracks.

Class `read` (reads only). Scopes `user-library-read`. Calls `GET /me/albums`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `limit` | integer | no | Maximum results per page, up to 50. Default 20. |
| `market` | string | no | ISO 3166-1 alpha-2 country code, e.g. "US". |
| `offset` | integer | no | Pagination offset. Default 0. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].added_at` | string |  |
| `items[].album` | object |  |
| `items[].album.artists` | array of object |  |
| `items[].album.id` | string |  |
| `items[].album.name` | string |  |
| `items[].album.release_date` | string |  |
| `total` | integer |  |

Also retrieved by: "what records have I kept", "show the albums I've collected", "my saved full-length releases".

### `spotify.save_albums`

Save one or more albums to the user's library. Use when the user wants to save or add a whole album to their library. Pass album ids comma separated. To remove one, use remove_saved_albums.

Class `write` (writes, no confirmation needed). Scopes `user-library-modify`. Calls `PUT /me/albums`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `album_ids` | string | **yes** | Comma-separated Spotify album ids. |

Also retrieved by: "keep this whole record", "add this release to my collection", "hang on to this album".

### `spotify.remove_saved_albums`

Remove one or more albums from the user's library. Use when the user wants to remove or take an album out of their saved library. Pass album ids comma separated. Undoable with save_albums.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `user-library-modify`. Calls `DELETE /me/albums`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `album_ids` | string | **yes** | Comma-separated Spotify album ids. |

Also retrieved by: "drop this record from my collection", "take this release out of my library", "stop keeping this album".

### `spotify.get_current_user_profile`

Get the connected account's own Spotify profile: display name, email, country, and subscription plan. Use when the user asks about their own account, or when another tool needs the user's own id, like create_playlist.

Class `read` (reads only). Scopes `user-read-email`, `user-read-private`. Calls `GET /me`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `country` | string |  |
| `display_name` | string |  |
| `email` | string |  |
| `external_urls` | object |  |
| `external_urls.spotify` | string |  |
| `followers` | object |  |
| `followers.total` | integer |  |
| `id` | string |  |
| `product` | string |  |

Also retrieved by: "what account am I logged into", "my subscription plan", "my own account details".

### `spotify.get_user_top_items`

Get the user's most listened-to artists or tracks over a time window. Use when the user asks what they listen to most, their top songs, or their top artists. item_type picks artists or tracks.

Class `read` (reads only). Scopes `user-top-read`. Calls `GET /me/top/{{params.item_type}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `item_type` | string, one of artists, tracks | **yes** | Which kind of top item to return. |
| `limit` | integer | no | Maximum results, up to 50. Default 20. |
| `offset` | integer | no | Pagination offset. Default 0. |
| `time_range` | string, one of short_term, medium_term, long_term | no | short_term is about 4 weeks, medium_term about 6 months, long_term several years. Default medium_term. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].artists` | array of object |  |
| `items[].artists[].id` | string |  |
| `items[].artists[].name` | string |  |
| `items[].genres` | array of string |  |
| `items[].id` | string |  |
| `items[].name` | string |  |
| `items[].popularity` | integer |  |

Also retrieved by: "what I've been listening to most", "my most played artists", "my heaviest rotation this year".

### `spotify.get_recently_played`

List tracks the user recently played, most recent first. Use when the user asks what they just listened to or their play history. Not for what's on right now; for that use get_playback_state.

Class `read` (reads only). Scopes `user-read-recently-played`. Calls `GET /me/player/recently-played`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `after` | integer | no | Only plays after this Unix timestamp in milliseconds. Cannot be combined with before. |
| `before` | integer | no | Only plays before this Unix timestamp in milliseconds. Cannot be combined with after. |
| `limit` | integer | no | Maximum results, up to 50. Default 20. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].played_at` | string |  |
| `items[].track` | object |  |
| `items[].track.album` | object |  |
| `items[].track.artists` | array of object |  |
| `items[].track.id` | string |  |
| `items[].track.name` | string |  |

Also retrieved by: "my listening history", "what I just had on", "what I listened to earlier today".

### `spotify.get_followed_artists`

List the artists the user currently follows. Use when the user asks who they follow or which artists are in their following list. Spotify only supports listing followed artists, not followed users.

Class `read` (reads only). Scopes `user-follow-read`. Calls `GET /me/following`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `after` | string | no | Artist id to page from, taken from a previous page's last artist. |
| `limit` | integer | no | Maximum results, up to 50. Default 20. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `artists` | object |  |
| `artists.items` | array of object |  |
| `artists.items[].external_urls` | object |  |
| `artists.items[].genres` | array of string |  |
| `artists.items[].id` | string |  |
| `artists.items[].name` | string |  |
| `artists.items[].popularity` | integer |  |
| `artists.total` | integer |  |

Also retrieved by: "who am I subscribed to", "my followed musicians", "the acts I keep up with".

### `spotify.follow_artists_or_users`

Follow one or more artists or Spotify users. Use when the user wants to follow, subscribe to, or start following an artist or another Spotify user. Set item_type and pass ids comma separated. To follow a playlist instead, use follow_playlist.

Class `write` (writes, no confirmation needed). Scopes `user-follow-modify`. Calls `PUT /me/following`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `ids` | string | **yes** | Comma-separated Spotify artist or user ids. |
| `item_type` | string, one of artist, user | **yes** | Whether ids are artists or users. |

Also retrieved by: "subscribe to this musician", "start keeping up with this act", "add this person to who I follow".

### `spotify.unfollow_artists_or_users`

Unfollow one or more artists or Spotify users. Use when the user wants to unfollow, stop following, or remove an artist or user from who they follow. Set item_type and pass ids comma separated. Undoable with follow_artists_or_users.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `user-follow-modify`. Calls `DELETE /me/following`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `ids` | string | **yes** | Comma-separated Spotify artist or user ids. |
| `item_type` | string, one of artist, user | **yes** | Whether ids are artists or users. |

Also retrieved by: "stop keeping up with this act", "drop this musician from who I follow", "unsubscribe from this person".
