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

Exact same issue here.

I tried different way to generate the developer token (like https://github.com/mkoehnke/musickit-token-encoder or programmatically with https://github.com/IBM-Swift/Swift-JWT) but still the same 401 results for all search API calls (even with the official Adding Content to Apple Music sample code from Apple).

Note that generating a UserToken is also failing with my developerToken.

I've done the exact same thing and couldn't get it to work. I noticed it adds in a `typ: "JWT"` to the header, so maybe it's not supposed to have that.

I am having the same problem. Tired creating the token using 4 different approaches.


When I check the token using


https://jwt.io/


I noticed that I get an error that the signature is invalid. It's the same result despite which method I use to create the token.


I know this isn't a solution, but hoped that someone might be able to help point me in the right direction.

Hey Folks, I am facing the very same issue. Did you manage to find a way forward?

I'm also having the exact same issue. Would love to hear about any updates/resolutions if folks have found any.

I have exactly the same problem:

< HTTP/2 401

Been trying for three days now.

I know I did everything correct, still fails.

My "Apple Music" subscription is the free 3 month trial but I guess that should not matter?

It seems we are many developers facing the same problem, it must be some problem at Apple's end?


You can check your signed token here:

https://shawntabrizi.com/JWT-Decoder/

When I check my token(s), I get exactly the correct data back, team ID, key ID etc.

I have the same issue. Has anyone been able to resolve this?

I had the exact same issue, however, it's working for me today. I don't know if that was an issue with Apple or what. I'm using the same code as the original poster.

Still getting a 401, and am also using the same code

Having the same issue. Tried creating a new Key ID and regenerating the jwtToken but still not working. Every request returns a 401 Unauthorized

Same here! Would love to see a solution to this, looks like there is plenty of people with this issue...

OK, this embarrasing, but I had an extra character at the end of my Team ID. After correcting it, I am now able to successfully call the API. My apologies!

Hi all,


I have the same issue. I hope that you succeeded since the post exist.

So how did you do ?
I don't understand why it doesn't work.

Hi All,


I also have the same issue.

How did you solve it?
Can someone help me

Per the documentation on the library, please put the payload as the first argument in the sign method


https://github.com/auth0/node-jsonwebtoken


Payload should include

{
"iss": "DEF123GHIJ",
"iat": 1437179036,
"exp": 1493298100
}

per https://developer.apple.com/documentation/applemusicapi/getting_keys_and_creating_tokens

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);
});

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);
  }

Since this thread is still active.If you use jwt.io keep in mind that unix epoch time must be provided as integer not a string

Sorry to ***** this thread, but I found the cause of my issue - directly using Date.now() (javascript) which returns the date in milliseconds, not seconds. Using the following to set your iat/exp will work:

Math.floor(Date.now() / 1000)
401-Unauthorized developer token in Apple Music API
 
 
Q