Type in your question below and we'll check to see what answers we can find...
Loading article...
Submitting...
If you couldn't find any answers in the previous step then we need to post your question in the community and wait for someone to respond. You'll be notified when that happens.
Simply add some detail to your question and refine the title if needed, choose the relevant category, then post.
Before we can post your question we need you to quickly make an account (or sign in if you already have one).
Don't worry - it's quick and painless! Just click below, and once you're logged in we'll bring you right back here and post your question. We'll remember what you've already typed in so you won't have to do it again.
Please see below the most popular frequently asked questions.
Loading article...
Loading faqs...
Please see below the current ongoing issues which are under investigation.
Loading issue...
Loading ongoing issues...
I have premium account and signed through client credentials authorization, but I still get that message with status 403 and can't understand why. Could someone please help me?
const access_token = (
await axios({
method: "POST",
data: {
grant_type: "client_credentials",
scope: "user-modify-playback-state user-top-read",
},
url: "https://accounts.spotify.com/api/token",
headers: {
Authorization: `Basic ${Buffer.from(
this.clientId + ":" + this.clientSecret
).toString("base64")}`,
"Content-Type": "application/x-www-form-urlencoded",
},
})
).data.access_token;
try {
let res = await axios({
method: "PUT",
url: "https://api.spotify.com/v1/me/player/play",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
data: {
context_uri: "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr",
},
});
console.log("ARTIST", res);
} catch (err: any) {
// 403 status
console.log("THIS ERRROR\n ", err.response);
}
Solved! Go to Solution.
Here's an example Node.js app, without the need for installing any modules. You have to be able to see the console on your server, though.
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const https = require('https');
const clientId = 'YOUR_CLIENT_ID';
const clientSecret = 'YOUR_CLIENT_SECRET';
const redirectUri = 'http://localhost:3000/callback';
const scopes = ['user-modify-playback-state', 'user-top-read', 'user-read-playback-state'];
// Step 1: Get authorization code
function authorize() {
const authorizeUrl = 'https://accounts.spotify.com/authorize';
const queryParams = querystring.stringify({
response_type: 'code',
client_id: clientId,
scope: scopes.join(' '),
redirect_uri: redirectUri,
});
const authorizationUrl = `${authorizeUrl}?${queryParams}`;
console.log(`Please authorize the application by visiting this URL: ${authorizationUrl}`);
}
// Step 2: Get access and refresh tokens
async function getTokens(authorizationCode) {
const tokenUrl = 'https://accounts.spotify.com/api/token';
const data = querystring.stringify({
grant_type: 'authorization_code',
code: authorizationCode,
redirect_uri: redirectUri,
});
const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const options = {
hostname: 'accounts.spotify.com',
path: '/api/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${authHeader}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Step 3: Refresh access token
async function refreshAccessToken(refreshToken) {
const tokenUrl = 'https://accounts.spotify.com/api/token';
const data = querystring.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken,
});
const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const options = {
hostname: 'accounts.spotify.com',
path: '/api/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${authHeader}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Step 4: Example usage
async function exampleUsage(accessToken) {
// Get the user's top tracks
const topTracks = await getTopTracks(accessToken);
if (topTracks.length === 0) {
console.log('No top tracks found.');
return;
}
// Retrieve the album of the first top track
const topTrack = topTracks[0];
const album = await getAlbum(accessToken, topTrack.album.id);
if (!album) {
console.log('No album found.');
return;
}
// Get the user's available devices
const devices = await getAvailableDevices(accessToken);
if (devices.length === 0) {
console.log('No devices found.');
return;
}
// Retrieve the device ID of the first available device
const deviceId = devices[0].id;
// Play the album on the first available device
await playAlbum(accessToken, deviceId, album.uri);
console.log(`Playing album "${album.name}" by ${album.artists[0].name}`);
}
// Example function: Get the user's top tracks
async function getTopTracks(accessToken) {
const topTracksUrl = 'https://api.spotify.com/v1/me/top/tracks';
const options = {
hostname: 'api.spotify.com',
path: '/v1/me/top/tracks',
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data).items);
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Get album details
async function getAlbum(accessToken, albumId) {
const albumUrl = `https://api.spotify.com/v1/albums/${albumId}`;
const options = {
hostname: 'api.spotify.com',
path: `/v1/albums/${albumId}`,
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Get available devices
async function getAvailableDevices(accessToken) {
const devicesUrl = 'https://api.spotify.com/v1/me/player/devices';
const options = {
hostname: 'api.spotify.com',
path: '/v1/me/player/devices',
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data).devices);
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Play album on device
async function playAlbum(accessToken, deviceId, albumUri) {
const playbackUrl = `https://api.spotify.com/v1/me/player/play?device_id=${deviceId}`;
const options = {
hostname: 'api.spotify.com',
path: `/v1/me/player/play?device_id=${deviceId}`,
method: 'PUT',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
};
const data = JSON.stringify({
context_uri: albumUri,
});
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
if (res.statusCode === 204) {
resolve();
} else {
reject(new Error(`Error playing album. Status code: ${res.statusCode}`));
}
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Helper function: Wait for a specified duration
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Create a server to handle the callback
http.createServer(async (req, res) => {
const requestUrl = url.parse(req.url, true);
const code = requestUrl.query.code;
if (code) {
const tokens = await getTokens(code);
// Replace the following console.log with your desired actions
console.log('Access Token:', tokens.access_token);
console.log('Refresh Token:', tokens.refresh_token);
// Call the example function to run the code
await exampleUsage(tokens.access_token);
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Authentication successful! You can close this page now.');
} else {
res.statusCode = 400;
res.setHeader('Content-Type', 'text/plain');
res.end('Authorization code not found in the callback URL.');
}
}).listen(3000, () => {
console.log('Server listening on http://localhost:3000');
});
// Call the authorize function to start the login flow
authorize();
You can not use that endpoint and scopes with Client Credentials.
What do you mean? Using server I want to connect to server of Spotify and play some music, how can I do that?
Client Credentials Flow: "Since this flow does not include authorization, only endpoints that do not access user information can be accessed."
You should implement the Authorization Code Flow.
Edit: or the Authorization code with PKCE extension, or the Implicit grant.
But it requires a code, that I don't have and also a redirect_url which I have no idea why should I use it
I mean that in my app I can't use redirect_url, because there is no interacting with the browser, because I don't need it in my app
Then you can't make your app work.
It definitely won't work with client credentials.
Then how can I contact developers of Spotify, so that they could tell me what to do?
Everything you'll need is already documented:
https://developer.spotify.com/documentation/web-api/concepts/authorization
Yeah, client credentials is what I need, no?
No, one of these:
Because you'll need to Access User Resources.
And which one can I use fully on server side?
You can use the Authorization code for this, but you'll need to be able to log in once to get an access token and refresh token. Then, the sever can use the refresh token to get a new access token and refresh token when they are expired. If it doesn't get a new refresh token, it can keep using the old one.
And how should I make an redirect_url? I even don't have framework such as express in my application ( which means I can't use redirect_url )
Here's an example Node.js app, without the need for installing any modules. You have to be able to see the console on your server, though.
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const https = require('https');
const clientId = 'YOUR_CLIENT_ID';
const clientSecret = 'YOUR_CLIENT_SECRET';
const redirectUri = 'http://localhost:3000/callback';
const scopes = ['user-modify-playback-state', 'user-top-read', 'user-read-playback-state'];
// Step 1: Get authorization code
function authorize() {
const authorizeUrl = 'https://accounts.spotify.com/authorize';
const queryParams = querystring.stringify({
response_type: 'code',
client_id: clientId,
scope: scopes.join(' '),
redirect_uri: redirectUri,
});
const authorizationUrl = `${authorizeUrl}?${queryParams}`;
console.log(`Please authorize the application by visiting this URL: ${authorizationUrl}`);
}
// Step 2: Get access and refresh tokens
async function getTokens(authorizationCode) {
const tokenUrl = 'https://accounts.spotify.com/api/token';
const data = querystring.stringify({
grant_type: 'authorization_code',
code: authorizationCode,
redirect_uri: redirectUri,
});
const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const options = {
hostname: 'accounts.spotify.com',
path: '/api/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${authHeader}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Step 3: Refresh access token
async function refreshAccessToken(refreshToken) {
const tokenUrl = 'https://accounts.spotify.com/api/token';
const data = querystring.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken,
});
const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const options = {
hostname: 'accounts.spotify.com',
path: '/api/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${authHeader}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Step 4: Example usage
async function exampleUsage(accessToken) {
// Get the user's top tracks
const topTracks = await getTopTracks(accessToken);
if (topTracks.length === 0) {
console.log('No top tracks found.');
return;
}
// Retrieve the album of the first top track
const topTrack = topTracks[0];
const album = await getAlbum(accessToken, topTrack.album.id);
if (!album) {
console.log('No album found.');
return;
}
// Get the user's available devices
const devices = await getAvailableDevices(accessToken);
if (devices.length === 0) {
console.log('No devices found.');
return;
}
// Retrieve the device ID of the first available device
const deviceId = devices[0].id;
// Play the album on the first available device
await playAlbum(accessToken, deviceId, album.uri);
console.log(`Playing album "${album.name}" by ${album.artists[0].name}`);
}
// Example function: Get the user's top tracks
async function getTopTracks(accessToken) {
const topTracksUrl = 'https://api.spotify.com/v1/me/top/tracks';
const options = {
hostname: 'api.spotify.com',
path: '/v1/me/top/tracks',
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data).items);
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Get album details
async function getAlbum(accessToken, albumId) {
const albumUrl = `https://api.spotify.com/v1/albums/${albumId}`;
const options = {
hostname: 'api.spotify.com',
path: `/v1/albums/${albumId}`,
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Get available devices
async function getAvailableDevices(accessToken) {
const devicesUrl = 'https://api.spotify.com/v1/me/player/devices';
const options = {
hostname: 'api.spotify.com',
path: '/v1/me/player/devices',
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data).devices);
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
// Example function: Play album on device
async function playAlbum(accessToken, deviceId, albumUri) {
const playbackUrl = `https://api.spotify.com/v1/me/player/play?device_id=${deviceId}`;
const options = {
hostname: 'api.spotify.com',
path: `/v1/me/player/play?device_id=${deviceId}`,
method: 'PUT',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
};
const data = JSON.stringify({
context_uri: albumUri,
});
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
if (res.statusCode === 204) {
resolve();
} else {
reject(new Error(`Error playing album. Status code: ${res.statusCode}`));
}
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
// Helper function: Wait for a specified duration
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Create a server to handle the callback
http.createServer(async (req, res) => {
const requestUrl = url.parse(req.url, true);
const code = requestUrl.query.code;
if (code) {
const tokens = await getTokens(code);
// Replace the following console.log with your desired actions
console.log('Access Token:', tokens.access_token);
console.log('Refresh Token:', tokens.refresh_token);
// Call the example function to run the code
await exampleUsage(tokens.access_token);
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Authentication successful! You can close this page now.');
} else {
res.statusCode = 400;
res.setHeader('Content-Type', 'text/plain');
res.end('Authorization code not found in the callback URL.');
}
}).listen(3000, () => {
console.log('Server listening on http://localhost:3000');
});
// Call the authorize function to start the login flow
authorize();
Hey there you, Yeah, you! 😁 Welcome - we're glad you joined the Spotify Community! While you here, let's have a fun game and get…