SpotifyEx

A simple Elixir client for the Spotify Web API.

Installation

Add spotifyex to your list of dependencies in mix.exs:

def deps do
  [
    {:spotifyex, "~> 0.1.0"}
  ]
end

Quick Start

1. Get an Access Token

# Build authorization URL
url = SpotifyEx.Auth.authorize_url(
  "your_client_id",
  "http://localhost:4000/callback",
  scopes: ["playlist-modify-public", "playlist-read-private"]
)

# After user authorizes, exchange code for token
{:ok, tokens} = SpotifyEx.Auth.exchange_code(
  code,
  "your_client_id",
  "your_client_secret",
  "http://localhost:4000/callback"
)

access_token = tokens["access_token"]

2. Create a Client

client = SpotifyEx.client(access_token)

3. Make API Calls

# Search for an album
{:ok, results} = SpotifyEx.Search.search(client, "Radiohead OK Computer", type: "album")

# Get album tracks
album_id = results["albums"]["items"] |> List.first() |> Map.get("id")
{:ok, tracks} = SpotifyEx.Albums.get_album_tracks(client, album_id)

# Get track URIs
track_uris = Enum.map(tracks["items"], & &1["uri"])

# Create a playlist
{:ok, user} = SpotifyEx.Users.get_current_user(client)
{:ok, playlist} = SpotifyEx.Playlists.create_playlist(
  client,
  user["id"],
  "My Playlist",
  description: "Created with SpotifyEx"
)

# Add tracks to playlist
{:ok, _} = SpotifyEx.Playlists.add_tracks(client, playlist["id"], track_uris)

# Or replace all tracks (overwrite)
{:ok, _} = SpotifyEx.Playlists.replace_tracks(client, playlist["id"], track_uris)

Modules

Module Description
SpotifyEx.Auth OAuth authentication (authorization code flow, token refresh)
SpotifyEx.Search Search for albums, artists, tracks, playlists
SpotifyEx.Albums Get album info, tracks, saved albums, new releases
SpotifyEx.Artists Get artist info, albums, top tracks, related artists
SpotifyEx.Tracks Get track info, audio features, recommendations
SpotifyEx.Playlists Create, update, manage playlists
SpotifyEx.Users Get user profiles, manage follows
SpotifyEx.Player Playback control, queue management, recently played
SpotifyEx.Shows Get show info, episodes, saved shows
SpotifyEx.Episodes Get episode info, saved episodes
SpotifyEx.Audiobooks Get audiobook info, chapters, saved audiobooks
SpotifyEx.Chapters Get chapter info
SpotifyEx.Categories Browse categories
SpotifyEx.Genres Available genre seeds for recommendations
SpotifyEx.Markets Available markets

Authentication

SpotifyEx supports the Authorization Code flow:

# 1. Generate authorization URL
url = SpotifyEx.Auth.authorize_url(client_id, redirect_uri,
  scopes: ["playlist-modify-public", "user-read-private"],
  state: "random_state_string"
)

# 2. User visits URL and authorizes your app

# 3. Exchange authorization code for tokens
{:ok, %{
  "access_token" => access_token,
  "refresh_token" => refresh_token,
  "expires_in" => 3600
}} = SpotifyEx.Auth.exchange_code(code, client_id, client_secret, redirect_uri)

# 4. Refresh token when expired
{:ok, %{"access_token" => new_token}} = 
  SpotifyEx.Auth.refresh_token(refresh_token, client_id, client_secret)

For server-to-server calls without user context, use Client Credentials:

{:ok, %{"access_token" => token}} = 
  SpotifyEx.Auth.get_client_credentials(client_id, client_secret)

Error Handling

All API calls return {:ok, result} or {:error, %SpotifyEx.Error{}}:

case SpotifyEx.Albums.get_album(client, "invalid_id") do
  {:ok, album} ->
    IO.puts(album["name"])
    
  {:error, %SpotifyEx.Error{status: 404, reason: :not_found}} ->
    IO.puts("Album not found")
    
  {:error, %SpotifyEx.Error{status: 401, reason: :unauthorized}} ->
    IO.puts("Token expired, refresh needed")
    
  {:error, %SpotifyEx.Error{reason: :rate_limited}} ->
    IO.puts("Rate limited, try again later")
end

License

MIT