401-Unauthorized developer token in Apple Music API

I am trying to access API of Apple Music API

> https://developer.apple.com/documentation/applemusicapi


After creating the JWT developer token, when i try to access the API, An error of 401 - Unauthorized occurs.


I am doing it in the following way :


1) Registering a new music identifier > https://help.apple.com/developer-account/#/devce5522674?sub=dev0416b9004


2) Creating a MusicKit identifier and private key > https://help.apple.com/developer-account/#/devce5522674 also downloading the private key file.


3) Getting the Kid (Key Id) and issuer (Team Id) .


4) Running the following code to generate the token :


const jwt     = require("jsonwebtoken");          
const privateKey = fs.readFileSync("AuthKey_KEY_ID.p8").toString();      

const teamId     = TEAM_ID_HERE;      
const keyId      = KEY_ID_HERE;    

 const jwtToken = jwt.sign({}, privateKey, {                       
                                             algorithm: "ES256",                    
                                             expiresIn: "120d",                    
                                             issuer: teamId,
                                             header: {                             
                                                       alg: "ES256",
                                                      kid: keyId                       
                                             }             
                              });     
console.log(jwtToken);



And after that checking the code using the curl command :


curl -v -H 'Authorization: Bearer [developer token]' "https://api.music.apple.com/v1/catalog/us/songs/203709340"  


I am not sure what i am missing here. is it something related to access or is it my code.


P.S : I am the Account Holder, so it is not an issue related to role.



Thanks

Post not yet marked as solved Up vote post of akh123 Down vote post of akh123
13k views

Replies

having this issue with python cannot get the token working been working on it for hours please help! Just keep getting response 401



import jwt

import json

import requests

import time

keyfile = open("AuthKey_NBSNY9688H.pem","r")

key = keyfile.read()

time_now = time.time()

time_later = 1599097116

token = jwt.encode({'iss': 'WHW4BF9ZH6', 'iat':time_now, 'exp':time_later}, key ,headers={'kid':'NBSNY9688H','alg':'ES256'})

token = token.decode('UTF-8')

print(token)

url = 'https://api.music.apple.com/v1/'

headers = {'Authorization': "Bearer" + token}

response = requests.get(url,headers=headers)

print(response)

Hi,


Please try adding a space after Bearer

headers = {'Authorization': "Bearer " + token}


Hope that helps!

Hey guys, I had the same trouble and found a way to fix it, so if this thread is still active, here's the solution that worked for me:


Step 01. Importing Swift JWT to my project

Step 02. The private key must be inserted as a Multi-Line Literal Content:

let privateKey = """
-----BEGIN PRIVATE KEY-----
MIvcxFYBNEMwqIF73955MGFSS043MF
MRNBGSfgQOgOES24FMDsOSBhN+IFUD
FaNFDsNFDF0R09543gsNFSMLFDSOAb
-----END PRIVATE KEY-----
"""

Step 03. Generating a 5 months valid JWT

let signer = JWTSigner.es256(privateKey: Data(privateKey.utf8))
let calendar = Calendar.current
if let exp = calendar.date(byAdding: .month, value: 5, to: Date()) {
     let claims = ClaimsStandardJWT(iss: "ABCD1234EF", exp: exp, iat: Date())
     let header = Header(kid: "GHIJ5678KL")
     let myJWT = JWT(header: header, claims: claims)
     do {
          let signedJWT = try myJWT.sign(using: signer)
          print(signedJWT)
     } catch {
          print("JWT error: \(error)")
     }
}


And that should do the trick.

This might only apply to the python users, but if you decode using utf-8, that should produce a usable curl command.

ex. token = jwt.encode(payload, secret, algorithm=alg, headers=headers).decode("utf-8")

Today my python script start throwing 401 error, at the end I found that expiration date value was very big: 1 hour. After changing exp value to 20 minutes API accepted token again

If anyone still is having issues with this. Here's a working piece of NodeJS code that generates a valid JWT token:

var jwt = require('jsonwebtoken');
var fs = require('fs');

var privateKey = fs.readFileSync('./AuthKey.p8');

let now = new Date();
let nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
let nowEpoch = Math.round(now.getTime() / 1000); // number of seconds since Epoch, in UTC
let nextMonthEpoch = Math.round(nextMonth.getTime() / 1000); // number of seconds since Epoch, in UTC

var payload = {
	iss: '***', // TEAM ID
	iat: nowEpoch,
	exp: nextMonthEpoch
};

var options = {
	algorithm: 'ES256',
	header: {
		alg: 'ES256',
		kid: '***' // KEY ID
	}
};

jwt.sign(payload, privateKey, options, function(error, token) {
	console.log(error);
	console.log(token);
});
  • Hey I have the same code but it is still not working for me. It is giving me 401. Can you help me?

Add a Comment

Hi, everyone. I am generating the jwt on the fly, but when I make a frontend request for songs with the Authorization as Bearer Token, it returns a 401. Is there a special way to make the frontend request?

This is how I am making the request in a react frontend, I just want to see the list of albums.

const getAlbums = async () => {
    
let albums = await axios.get("https://api.music.apple.com/v1/catalog/us/albums", {
       headers: {
         headers: {
           Authorization: `Bearer ${token}`,
           Accept: "application/json",
           "Content-Type": "application/json",
         },
       },
     })
     .then((res) => console.log(res.data));

   console.log(albums);
  }