Agent Skills: spotify

Spotify Web API for music streaming. Use when user mentions "Spotify", "play music", "Spotify playlist", "top tracks", "now playing", "Spotify artist", or asks about music playback or library.

UncategorizedID: vm0-ai/vm0-skills/spotify

Install this agent skill to your local

pnpm dlx add-skill https://github.com/vm0-ai/vm0-skills/tree/HEAD/spotify

Skill Files

Browse the full folder contents for spotify.

Download Skill

Loading file tree…

spotify/SKILL.md

Skill Metadata

Name
spotify
Description
Spotify Web API for music streaming. Use when user mentions "Spotify", "play music", "Spotify playlist", "top tracks", "now playing", "Spotify artist", or asks about music playback or library.

Troubleshooting

If requests fail, run zero doctor check-connector --env-name SPOTIFY_TOKEN or zero doctor check-connector --url https://api.spotify.com/v1/me --method GET

User Profile

Get Current User Profile

curl -s "https://api.spotify.com/v1/me" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '{id, display_name, email, product, followers: .followers.total}'

Search

Search Tracks, Artists, Albums, or Playlists

Write to /tmp/spotify_query.txt:

<your-search-query>
curl -s -G "https://api.spotify.com/v1/search" --header "Authorization: Bearer $SPOTIFY_TOKEN" --data-urlencode "q@/tmp/spotify_query.txt" --data-urlencode "type=track,artist,album" -d "limit=5" | jq '{tracks: [.tracks.items[]? | {id, name, artists: [.artists[].name], album: .album.name, uri}], artists: [.artists.items[]? | {id, name, genres, uri}]}'

To search for playlists only:

curl -s -G "https://api.spotify.com/v1/search" --header "Authorization: Bearer $SPOTIFY_TOKEN" --data-urlencode "q@/tmp/spotify_query.txt" --data-urlencode "type=playlist" -d "limit=5" | jq '[.playlists.items[]? | {id, name, owner: .owner.display_name, tracks: .tracks.total, uri}]'

Personalized Data

Get Top Tracks

Requires scope: user-top-read.

time_range options: short_term (4 weeks), medium_term (6 months), long_term (all time).

curl -s "https://api.spotify.com/v1/me/top/tracks?limit=20&time_range=medium_term" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.items[] | {name, artists: [.artists[].name], album: .album.name, uri}]'

Get Top Artists

Requires scope: user-top-read.

curl -s "https://api.spotify.com/v1/me/top/artists?limit=20&time_range=medium_term" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.items[] | {name, genres, popularity, uri}]'

Get Recently Played Tracks

Requires scope: user-read-recently-played.

curl -s "https://api.spotify.com/v1/me/player/recently-played?limit=20" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.items[] | {played_at, track: .track.name, artists: [.track.artists[].name], uri: .track.uri}]'

Playlists

List Current User's Playlists

Requires scope: playlist-read-private.

curl -s "https://api.spotify.com/v1/me/playlists?limit=20" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.items[] | {id, name, owner: .owner.display_name, total_tracks: .tracks.total, uri}]'

Get Playlist Tracks

Replace <playlist-id> with the actual playlist ID:

curl -s "https://api.spotify.com/v1/playlists/<playlist-id>/tracks?limit=50&fields=items(track(id,name,artists,album(name),uri))" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.items[] | {name: .track.name, artists: [.track.artists[].name], album: .track.album.name, uri: .track.uri}]'

Create Playlist

Requires scope: playlist-modify-public or playlist-modify-private.

First, get your user ID:

curl -s "https://api.spotify.com/v1/me" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq -r '.id'

Write to /tmp/spotify_playlist.json:

{
  "name": "<your-playlist-name>",
  "description": "<your-playlist-description>",
  "public": false
}

Replace <user-id> with your Spotify user ID:

curl -s -X POST "https://api.spotify.com/v1/users/<user-id>/playlists" --header "Authorization: Bearer $SPOTIFY_TOKEN" --header "Content-Type: application/json" -d @/tmp/spotify_playlist.json | jq '{id, name, uri}'

Add Tracks to Playlist

Requires scope: playlist-modify-public or playlist-modify-private.

Write to /tmp/spotify_add_tracks.json:

{
  "uris": [
    "spotify:track:<track-id-1>",
    "spotify:track:<track-id-2>"
  ]
}

Replace <playlist-id> with the target playlist ID:

curl -s -X POST "https://api.spotify.com/v1/playlists/<playlist-id>/tracks" --header "Authorization: Bearer $SPOTIFY_TOKEN" --header "Content-Type: application/json" -d @/tmp/spotify_add_tracks.json | jq '{snapshot_id}'

Playback Control

Requires Spotify Premium. All playback endpoints need an active Spotify client running on a device.

Get Playback State

Requires scope: user-read-playback-state.

curl -s "https://api.spotify.com/v1/me/player" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '{device: .device.name, is_playing, track: .item.name, artists: [.item.artists[]?.name], progress_ms, duration_ms: .item.duration_ms}'

Start or Resume Playback

Requires scope: user-modify-playback-state.

Play a specific playlist or album by URI:

Write to /tmp/spotify_play.json:

{
  "context_uri": "spotify:playlist:<playlist-id>"
}
curl -s -X PUT "https://api.spotify.com/v1/me/player/play" --header "Authorization: Bearer $SPOTIFY_TOKEN" --header "Content-Type: application/json" -d @/tmp/spotify_play.json

Play specific tracks by URI:

Write to /tmp/spotify_play.json:

{
  "uris": [
    "spotify:track:<track-id-1>",
    "spotify:track:<track-id-2>"
  ]
}
curl -s -X PUT "https://api.spotify.com/v1/me/player/play" --header "Authorization: Bearer $SPOTIFY_TOKEN" --header "Content-Type: application/json" -d @/tmp/spotify_play.json

Pause Playback

Requires scope: user-modify-playback-state.

curl -s -X PUT "https://api.spotify.com/v1/me/player/pause" --header "Authorization: Bearer $SPOTIFY_TOKEN"

Skip to Next Track

Requires scope: user-modify-playback-state.

curl -s -X POST "https://api.spotify.com/v1/me/player/next" --header "Authorization: Bearer $SPOTIFY_TOKEN"

Skip to Previous Track

Requires scope: user-modify-playback-state.

curl -s -X POST "https://api.spotify.com/v1/me/player/previous" --header "Authorization: Bearer $SPOTIFY_TOKEN"

Set Volume

Requires scope: user-modify-playback-state. Replace <volume> with a value between 0 and 100:

curl -s -X PUT "https://api.spotify.com/v1/me/player/volume?volume_percent=<volume>" --header "Authorization: Bearer $SPOTIFY_TOKEN"

Albums & Artists

Get Album

Replace <album-id> with the Spotify album ID:

curl -s "https://api.spotify.com/v1/albums/<album-id>" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '{id, name, artists: [.artists[].name], release_date, total_tracks, uri}'

Get Artist

Replace <artist-id> with the Spotify artist ID:

curl -s "https://api.spotify.com/v1/artists/<artist-id>" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '{id, name, genres, popularity, followers: .followers.total, uri}'

Get Artist's Top Tracks

Replace <artist-id> with the Spotify artist ID:

curl -s "https://api.spotify.com/v1/artists/<artist-id>/top-tracks" --header "Authorization: Bearer $SPOTIFY_TOKEN" | jq '[.tracks[] | {name, album: .album.name, popularity, uri}]'

Guidelines

  1. Token Expiry: Access tokens expire after 1 hour. A 401 response means the token needs refreshing via the Connector settings.
  2. Scopes: Different endpoints require different OAuth scopes. Ensure the connected Spotify app has the necessary scopes granted (listed per endpoint above).
  3. Premium Required: All playback control endpoints (/me/player/play, /me/player/pause, /me/player/next, etc.) require a Spotify Premium subscription.
  4. Rate Limits: Spotify enforces rate limits. If you receive a 429 response, back off and retry after the Retry-After header value (in seconds).
  5. Spotify URIs vs IDs: Resources can be referenced by URI (spotify:track:<id>) or bare ID depending on the endpoint. Search results include both id and uri fields.