A PHP wrapper for Spotify's Web API.

Overview

Spotify Web API PHP

Packagist build Coverage Status

This is a PHP wrapper for Spotify's Web API. It includes the following:

  • Helper methods for all API endpoints:
    • Information about artists, albums, tracks, podcasts, and users.
    • List music featured by Spotify.
    • Playlist and user music library management.
    • Spotify catalog search.
    • User playback control.
  • Authorization flow helpers.
  • Automatic refreshing of access tokens.
  • Automatic retry of rate limited requests.
  • PSR-4 autoloading support.

Requirements

Installation

Install it using Composer:

composer require jwilsson/spotify-web-api-php

Usage

Before using the Spotify Web API, you'll need to create an app at Spotify’s developer site.

Simple example displaying a user's profile:

require 'vendor/autoload.php';

$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET',
    'REDIRECT_URI'
);

$api = new SpotifyWebAPI\SpotifyWebAPI();

if (isset($_GET['code'])) {
    $session->requestAccessToken($_GET['code']);
    $api->setAccessToken($session->getAccessToken());

    print_r($api->me());
} else {
    $options = [
        'scope' => [
            'user-read-email',
        ],
    ];

    header('Location: ' . $session->getAuthorizeUrl($options));
    die();
}

For more instructions and examples, check out the documentation.

The Spotify Web API Console can also be of great help when trying out the API.

Contributing

Contributions are more than welcome! See CONTRIBUTING.md for more info.

License

MIT license. Please see LICENSE.md for more info.

Comments
  • Invalid authorization code

    Invalid authorization code

    Hi

    I'm having a problem.... https://beta.cloudmoosic.com/music/spotify/login After login I'm getting the Invalid Authorization Code Error, I've used the examples you gave but it's still not working....

    Any idea on how to fix this?

    opened by matthijsotterloo 27
  •  Fatal error

    Fatal error

    Hello, im trying to use the spotify api, worked really good, but now i'm having some issues which i'm not being able to fix

    /vendor/jwilsson/spotify-web-api-php/src/Request.php(239): SpotifyWebAPI\Request->handleResponseError(Object(stdClass), 403) #1 /home/akaggdvp/public_html/test-flc/api/vendor/jwilsson/spotify-web-api-php/src/Request.php(129): SpotifyWebAPI\Request->send('GET', 'https://api.spo...', '', Array) /vendor/jwilsson/spotify-web-api-php/src/SpotifyWebAPI.php(124): SpotifyWebAPI\Request->api('GET', '/v1/me', Array, Array) /vendor/jwilsson/spotify-web-api-php/src/SpotifyWebAPI.php(1556): SpotifyWebAPI\SpotifyWebAPI->sendRequest('GET', '/v1/me') vendor/index.php(16): SpotifyWebAPI\SpotifyWebAPI->me(Object(SpotifyWebAPI\Session)) #5 {main} thrown in /vendor/jwilsson/spotify-web-api-php/src/Request.php on line 59

    removed the /home/ dir, etc.

    I'm not sure if the "array" means that the client id and secret aren't getting read, but, if there's any possible fix, let me know.

    question 
    opened by Fl3ecy 18
  • support php5.6 too

    support php5.6 too

    First, thanks for this awesome package.

    I have to use it on a server which runs php 5.6, but this package is not support it. I checked the source and there is no serious reason to restrict minimum php version to 7.0 :)

    With wider requirements your package can reach more people :)

    opened by albertborsos 15
  • Authentication example could be better

    Authentication example could be better

    This library provides a great and broad abstraction of the Spotify Web API. Thank you for that.

    The authentication example is not so good though, and doesn't work the way it's written.

    This is how I did it. Note that everything is done in a single script, including all app state.

    The try/catch should probably cover more than it does.

    define('CLIENT_ID', 'xxxxxxxxxxxxxxxxxxxxxx');
    define('CLIENT_SECRET', 'xxxxxxxxxxxxxxxxxxxxxxxx');
    define('REDIRECT_URI', "http" . (!empty($_SERVER['HTTPS']) ? "s" : "") . "://" . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME']);
    define('SESSION', 'spotify_access_token');
    
    ...
    
    $session = new SpotifyWebAPI\Session(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
    
    if (isset($_GET['code'])):
        $session->requestAccessToken($_GET['code']);
        $accessToken = $session->getAccessToken();
        $_SESSION[SESSION] = $accessToken;
        header('Location: index.php');
        die();
    elseif (!isset($_SESSION[SESSION])):
        $options = ['scope' =>
            [
                'user-read-private',
                'user-read-email',
                'user-read-birthdate',
                'user-top-read',
                'playlist-read-private',
                'playlist-modify-private',
                'playlist-read-collaborative',
                'playlist-modify-public',
                'ugc-image-upload'
            ]
        ];
        header('Location: ' . $session->getAuthorizeUrl($options));
        die();
    else:
        $accessToken = $_SESSION[SESSION];
    endif;
    
    try {
        $api = new SpotifyWebAPI\SpotifyWebAPI();
        $api->setAccessToken($accessToken);
        $api->setReturnType(SpotifyWebAPI\SpotifyWebAPI::RETURN_ASSOC);
    
        $me = $api->me();
        $userName = $me['display_name'];
        $userId = $me['id'];
        $userPicture = $me['images'][0]['url'];
    }
    catch (Exception $ex) {
        unset($_SESSION[SESSION]);
        header('Location: index.php');
        die();
    }
    
    docs 
    opened by andersborgabiro 15
  • Automatic refresh of access token

    Automatic refresh of access token

    Hey, if I did not miss anything we have two options to notice that an access token refresh is needed:

    • An api call throws a SpotifyWebAPIException with message 'access token expired'.
      • Then we have to refresh the token and run the call again.
    • We check the expirationTime before the request.
      • Then we have to refresh the token and run the call.

    To me this seems something that could be automated, because basically every developer using this library is going to need this at some point. I thought of something like this:

    class SpotifyWebAPI {
        public function __construct($request = null, $autoRefreshAccessToken = true) {
        // ...
    

    I could try to make a PR if this would be desired functionality.

    enhancement help wanted 
    opened by henk23 14
  • User can´t login

    User can´t login

    Hello,

    I want the User to login with Authorization Code Flow. I literally copied your example code without any success.

    That´s my function called "authentication". First time I called this function is when the user clicked on the login button, that´s works fine. At the end of the function I send the request to the spotify URL that comes from "getAuthorizeUrl($options)" and the redirect URL send the request right back to the same function where I check if $_GET['code'] is set. But the $_GET['code'] is not set consistently.

    It works fine a few Days ago, I dont know what I have done to make this broken.

    Sorry for my english. I dont communicate often in this Language, because I life in Germany. If you have some understanding asks because of my bad english, feel free to ask.

    ` public function authentication() { $session = new Session( 'c16933d6f92f4379a698322d4e273e69', '3180bd72eb9e4c65a26cd1e770590bd3', 'http://localhost:8081/api/spotifyLogin' );

    if(isset($_GET['code']))
    {
      $session->requestAccessToken($_GET['code']);
    
      $accessToken = $session->getAccessToken();
      $refreshToken = $session->getRefreshToken();
    
      $_SESSION['userAccessToken'] = $accessToken;
      $_SESSION['userRefreshToken'] = $refreshToken;
    
      header('Location: ' . $_SERVER['HTTP_HOST'] . $_SESSION['REQUEST_URI']);
      die();
    }
    
      $options = [
        'scope' => [
          'playlist-read-private',
          'user-read-private',
        ],
      ];
    
      header('Location: ' . $session->getAuthorizeUrl($options));
      die();
    

    }`

    question 
    opened by philliphemleb 13
  • Uncaught exception 'SpotifyWebAPI\SpotifyWebAPIException'

    Uncaught exception 'SpotifyWebAPI\SpotifyWebAPIException'

    Hello,

    I think I'm having the same issue that https://github.com/jwilsson/spotify-web-api-php/issues/29. Here's my error: 1430432140-spotify-error.png - envoi d'image avec NoelShack

    So, when I launch index.php it asks me the authorization and when I say 'yes' I'm getting this. I have an another page callback.php which is called once the user clicks on 'yes'. These two pages only contain the code provided by you. I tried to run it on both Linux and Windows :)

    If you need anything, ask me ! Thanks in advance, it's really important for me to solve this problem :+1:

    Audric.

    opened by BillyCallahan 13
  • cURL transport error: 28 Failed to connect

    cURL transport error: 28 Failed to connect

    I have a small personal application which I use to connect to spotify. It's fairly simple, I run it locally.

    However, sometimes™, sending any request to the SpotifyWebAPI will result in the process hanging for rougly 30 seconds, after which I get the following error:

    127.0.0.1:59078 [200]: GET /?refresh=true - Uncaught SpotifyWebAPI\SpotifyWebAPIException: cURL transport error: 28 Failed to connect to api.spotify.com port 443: Connection timed out in /home/.../srcdir/vendor/jwilsson/spotify-web-api-php/src/Request.php:223
    

    I don't think there's an issue with access/refresh tokens, those are handled and any error in the access token causes a raise like I would expect.

    I also don't think there's a rate limit, because I'm not receiving 429 errors, just a timeout.

    I would personally be fine if curl just returned an error after a timeout of 1 second. But for some reason setting curlopts doesn't cause a timeout any faster than the 60 seconds I'm now seeing.

    Anyone experience with this? Am I missing something? This is roughly my implementation:

    <?php
    
    function spotify()
    {
      global $_spotify;
    
      if(! isset($_spotify)) {
        $_spotify = new SpotifyWebAPI\SpotifyWebSPI(
          [
            'auto_refresh' => false,
            'auto_retry' => false,
          ],
          spotify_session()
        );
      }
    
      if(time() >= (value("spotify_token_expiration") - 120)) {
        spotify_session()->refreshAccessToken(spotify_session()->getRefreshToken());
    
        value("spotify_token_expiration", spotify_session()->getTokenExpiration());
        value("spotify_access_token", spotify_session()->getAccessToken());
        value("spotify_refresh_token", spotify_session()->getRefreshToken());
      }
    
      return $_spotify;
    }
    
    function spotify_session()
    {
      global $_spotify_session;
    
      if(! isset($_spotify_session)) {
        $SPOTIFY_CLIENT_ID = 'redacted';
        $SPOTIFY_CLIENT_SECRET = 'redacted';
    
        $SPOTIFY_ACCESS_TOKEN = value("spotify_access_token");
        $SPOTIFY_REFRESH_TOKEN = value("spotify_refresh_token");
    
        $_spotify_session = new SpotifyWebAPI\Session(
            $SPOTIFY_CLIENT_ID,
            $SPOTIFY_CLIENT_SECRET
        );
    
        $_spotify_session->setAccessToken($SPOTIFY_ACCESS_TOKEN);
        $_spotify_session->setRefreshToken($SPOTIFY_REFRESH_TOKEN);
      }
    
      return $_spotify_session;
    }
    

    (and then using spotify()->me() and such in the application).

    question 
    opened by dinandmentink 9
  • Tutorial for a noob please?

    Tutorial for a noob please?

    Dear everyone!

    I am very new with the spotify api. I followed this link after I had a good read, but I am not very familiar with how can I achieve a couple of functions.

    I am happy and ready to pay for someone's time to help me achieve on how to increase followers on a playlist via this spotify api.

    Unless it is not possible to use this api for such function!

    Please let me know, Chris Black

    opened by ChrisBlackCH 9
  • refreshAccessToken no param, setter doco needed

    refreshAccessToken no param, setter doco needed

    Found a mismatch with current Session.php and doco regarding refreshing access tokens, that method has no param, so you need to call seperate setter if not in same execution flow as retrieving the access token itself.

    opened by dabros 9
  • Refresh token should not be in Session

    Refresh token should not be in Session

    Just wanted to check whether you guys would agree on this, or not.

    In my opinion, the refresh_token should not exist in the Session class. It should just be returned by Session::requestToken() (I refactored that to Session::requestRefreshAndAccessToken() in https://github.com/jwilsson/spotify-web-api-php/pull/19) and be supplied when the access token is refreshed.

    Why? Well, at the moment it is stored in the class for convenience, but no one would be using it like this. The access token expiration takes quite long (one hour at the moment), that anyone using the refresh token should already save it somewhere persistent. By removing it from the class, it will be more obvious the refresh token is not something volatile. Plus you leave it up to the user to do something with the token or not.

    Therefore, I'd like to suggest to:

    • Remove Session::$refreshToken (plus its associated get and set methods)
    • Change Session::requestToken() (Session::requestRefreshAndAccessToken() in https://github.com/jwilsson/spotify-web-api-php/pull/19) to return an array containing the three returned values (access token, expiry date, and the refresh token) and null when something goes wrong.
    • Change Session::refreshToken() (Session::refreshAccessToken() in https://github.com/jwilsson/spotify-web-api-php/pull/19) to have the refresh token as a parameter.

    Next, something that just came to my mind: the access token's expire period also doesn't do much. I.e. it's saved, but you know nothing of it (e.g. when was the last access token retrieved). So we should either do something with it (calculate when the access token actually expires and act on it), or just leave this to the user of the class...

    Just some ideas, wonder what you guys think ;].

    feedback wanted 
    opened by hvt 9
  • using the wrapper without composer

    using the wrapper without composer

    I have downloaded and unzipped the code archive. there is a folder src which has all the wrapper's class files (I guess). how do I use it with plain simple PHP without composer. please advise. thank you.

    question 
    opened by humpataa 1
  • getPlaylistTracks gives the different tracks for playlist generated by user: Spotify when using the API vs using the Spotify sandpit console

    getPlaylistTracks gives the different tracks for playlist generated by user: Spotify when using the API vs using the Spotify sandpit console

    I have a server-side app that auths using the Client Credential Flow i.e:

    $session = new SpotifyWebAPI\Session($this->clientId_,$this->clientSecret_);
    $session->requestCredentialsToken();
    $this->accessToken_ = $session->getAccessToken();
    

    I then attempt to read a normal user playlist for example:

    $uri='spotify:playlist:0inHe5mbRJoHBtPl8dWMYg';
    $playlist = $this->spotify_->api()->getPlaylistTracks($uri, ['market' => 'GB','offset' => $offset, 'limit' => $limit]);
    print_r($playlist);
    die();
    

    I get the expected results i.e. the tracks in the users playlist that I see in the Spotify app.

    If I try to do the same with a playlist a smart playlist owned by Spotify for instance "Daily Mix"

    $uri='spotify:playlist:37i9dQZF1E395IXQUXa6QW';
    $playlist = $this->spotify_->api()->getPlaylistTracks($uri, ['market' => 'GB','offset' => $offset, 'limit' => $limit]);
    print_r($playlist);
    die();
    

    Again it works as fine and as expected.

    If I then try a Playlist owned by Spotify in this case "Lovely Little Playlist"

    https://open.spotify.com/playlist/37i9dQZF1DWXRqgorJj26U?si=a4d80532c53844f8

    $uri='spotify:playlist:37i9dQZF1DXbZndSu0dHeI';
    $playlist = $this->spotify_->api()->getPlaylistTracks($uri, ['market' => 'GB','offset' => $offset, 'limit' => $limit]);
    print_r($playlist);
    die();
    

    I get a slightly different tracks being returned than I see in the Spotify app. There is a lot of commonality but there are also differences (though interestingly all tracks are the correct style of music.)

    If I try this in the Spotify sandpit console (using the OAuth token generated by the console.)

    https://developer.spotify.com/console/get-playlist-tracks/?playlist_id=37i9dQZF1DXbZndSu0dHeI&market=&fields=&limit=&offset=&additional_types=

    I get the tracks I see in the Spotify app

    And if I copy the curl command generated by the sandpit console and run it on my server:

    curl -X "GET" "https://api.spotify.com/v1/playlists/37i9dQZF1DXbZndSu0dHeI/tracks?market=GB" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer BQDdrL4L74e_GtbbhDRU0xAYOSV2AMHvntrwacbLdpfBIL9FbMRMJjaoRfSfEdI8kxPqLCtn7AZkHk_HtGjFAC0jOxIgQWlRe-TjNnEoSyinCPa05PaBNUnkXnaCsP7dCOgVQa72aeGw"
    

    It also gives the tracks I see in the Spotify app.

    However if I trace down into the Request.php get the Auth token generated by the Client Credentials flow and put into the above curl request i.e.

    curl -X "GET" "https://api.spotify.com/v1/playlists/37i9dQZF1DXbZndSu0dHeI/tracks?market=GB" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer BQDwQ8vqob0tLLH2hNbpMru7wqxYXZ_3dbolc0gHBnobpUCPBHSDzaJRWPIXZkuZmOj0WjpeBXssPnB0Ne8"
    

    I get a slightly different set of tracks returned. Again commonality but differences.

    NB. Market is set to "GB" in both cases and I have checked is_playable is true or 1 in for all tracks

    So my questions would be :

    1. Is there something else I should be specifying to get the same tracks for both spoti-web-api-php vs sandpit console?

    2. Do you think this is to do with the different auth flows or is that a red herring?

    3; Do you think this is because "Lovely Little Playlist" is an actually a smart playlist, the tracks being generated dynamically and thus not tightly defined - essentially the behaviour I'm seeing is to be expected.

    And finally, If this the right place to ask the question or should I post it on the Spotify dev forums instead.

    Many thanks for any insight you can give.

    question 
    opened by adamvietnam 7
  •  cURL transport error: 7 Failed to connect to api.spotify.com port 443: Timed out in

    cURL transport error: 7 Failed to connect to api.spotify.com port 443: Timed out in

    Since about a year my scripts stop in the middle of my page with the curl transport error (see subject). I tried adding a sleep(1) command but it doesn't help much.

    Many thanks

    question 
    opened by omadepod 12
Owner
Jonathan Wilsson
Jonathan Wilsson
This package is a simple API laravel wrapper for Pokemontcg with a sleek Model design for API routes and authentication.

This package is a simple API laravel wrapper for Pokemontcg with a sleek Model design for API routes and authentication.

Daniel Henze 3 Aug 29, 2022
Simple Curl based wrapper for Binance API for PHP scripts

Simple Curl based wrapper for Binance API for PHP scripts Feaures API support for SPOT data/trading FAPI/DAPI support for futures data/trading Curl-on

Mr Crypster 22 May 1, 2022
Google Drive Api Wrapper by PHP

GoogleDrive Api Wrapper usage at first you need to create oauth client on google cloud platform. so go to the your google console dashboard and create

Arash Abedi 2 Mar 24, 2022
Twitch Helix API PHP Wrapper for Laravel

Laravel Twitch PHP Twitch Helix API Wrapper for Laravel 5+ ⚠️ Changes on May 01, 2020 Since May 01, 2020, Twitch requires all requests to contain a va

Roman Zipp 87 Dec 7, 2022
Super-simple, minimum abstraction MailChimp API v3 wrapper, in PHP

MailChimp API Super-simple, minimum abstraction MailChimp API v3 wrapper, in PHP. I hate complex wrappers. This lets you get from the MailChimp API do

Drew McLellan 2k Dec 22, 2022
Google Translator Api Wrapper For Php Developers.

Google Translator Api Wrapper For Php Developers.

Roldex Stark 2 Oct 12, 2022
The Official Vultr API PHP Wrapper

WIP - This is not the final API Client. Unstable release use with caution. Vultr API PHP Client. Getting Started Must have a PSR7, PSR17, and PSR18 Co

Vultr 10 Dec 20, 2022
An elegant wrapper around Google Vision API

STILL UNDER DEVELOPMENT - DO NOT USE IN PRODUCTION Requires PHP 8.0+ For feedback, please contact me. This package provides an elegant wrapper around

Ahmad Mayahi 24 Nov 20, 2022
An unofficial wrapper client for lknpd.nalog.ru API

Unofficial MoyNalog API client An unofficial wrapper client for lknpd.nalog.ru API Install Via Composer $ composer require shoman4eg/moy-nalog Usage S

Artem Dubinin 18 Dec 14, 2022
A Gitlab API wrapper that helps to automate common actions on CI jobs

Gitlab CI client This is a Gitlab API wrapper that helps to automate common actions on CI jobs (eg: Open a merge request, Open or close an issue etc)

SparkFabrik 2 May 2, 2022
A PHP Stream wrapper for Amazon S3

S3StreamWrapper A simple stream wrapper for Amazon S3. Example <?php use S3StreamWrapper\S3StreamWrapper; S3StreamWrapper::register(); $options = a

Gijs Kunze 21 Nov 23, 2021
An asynchronous ClamAV wrapper written in PHP with amphp/socket

amphp-clamav An asynchronous ClamAV wrapper written with amphp/socket Installing composer require pato05/amphp-clamav Examples Ping and scan of a fil

Pato05 4 Feb 28, 2022
Laravel wrapper for the Facebook Graph PHP 8 SDK

Laravel Facebook Graph SDK Installation Getting started with Laravel Facebook Graph is easy - first, install the package via composer composer require

Joel Butcher 44 Dec 8, 2022
OVHcloud APIs lightweight PHP wrapper

Lightweight PHP wrapper for OVHcloud APIs - The easiest way to use OVHcloud APIs in your PHP applications - Compatible with PHP 7.4, 8.0, 8.1 - Not affiliated with OVHcloud

Germain Carré 3 Sep 10, 2022
laravel wrapper for dicom images services

laravel wrapper for dicom images services

Laravel Iran Community 4 Jan 18, 2022
A Laravel wrapper for thephpleague's Fractal package

laravel-api-response A Laravel wrapper for thephpleague's Fractal package Install Via Composer composer require lykegenes/laravel-api-response Then, a

Patrick Samson 3 Mar 15, 2021
PSR-18 compliant Circuit Breaker wrapper

Interrupt PSR-18 compliant Circuit Breaker wrapper. Acknowledgement This library is heavily inspired by: ackintosh/ganesha PrestaShop/circuit-breaker

Flávio Heleno 5 Jun 14, 2023
This library allows you to quickly and easily use the Twilio SendGrid Web API v3 via PHP

This library allows you to quickly and easily use the Twilio SendGrid Web API v3 via PHP

Twilio SendGrid 1.4k Dec 27, 2022
Nexmo REST API client for PHP. API support for SMS, Voice, Text-to-Speech, Numbers, Verify (2FA) and more.

Client Library for PHP Support Notice This library and it's associated packages, nexmo/client and nexmo/client-core have transitioned into a "Maintena

Nexmo 75 Sep 23, 2022