I ran into a similar problem, but that was because I tried to use the auth token directly as the Authorization header of my Server API requests... Then I came across (Apple Documentation).
But, that doesn't seem to be your issue, since you are in fact trying to call for an access token.
I do see some differences to my own implementation, however, which I can suggest to you as possible experimentations:
Like @DTS Engineer said, it may be worth it to refactor your time format:
iat: Date.now() / 1000,
exp: (Date.now() / 1000) + (60 * 60 * 24 * 7),
There is namely a difference:
const byThousand = {
base: Date.now() / 1000,
expire: (Date.now() / 1000) + (60 * 60 * 24 * 7),
}
const notByThousand = {
base: Date.now(),
expire: Date.now() + (1000 * 30 * 60),
}
function print() {
console.log("byThousand:");
console.log(JSON.stringify(byThousand, null, 4));
console.log("notByThousand:");
console.log(JSON.stringify(notByThousand, null, 4));
}
print();
// output:
//
// byThousand:
// {
// "base": 1735557622.287,
// "expire": 1736162422.287
// }
// notByThousand:
// {
// "base": 1735557622287,
// "expire": 1735559422287
// }
Leave Authorization out of any quotes:
Authorization: ...
(Instead of):
'Authorization': ...
Simplify your token string with interpolation:
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
});
Check and verify there are no misconfigurations in TeamID, KeyID, and your private key path.
Perhaps log the headers to the console in your requests, so you can inspect if anything's off with what you're sending.
If that doesn't resolve it, I'd be curious to see your console logs.