SUCCESS! Had a labs call with two Apple engineers and they set me on the right path.
This is what your JWT should look like:
var privateKey = fs.readFileSync("YOU KEY FILE FROM DEVELOPER CENTER.p8");
var token = jwt.sign(
{
subject: "APP ID",
},
privateKey,
{
jwtid: "YOUR TEAM ID.YOUR APP ID",
issuer: "TEAM ID",
expiresIn: "1h",
keyid: "KEY ID",
algorithm: "ES256",
header: {
id: "YOUR TEAM ID.YOUR APP ID",
},
}
);
// id is teamid.serviceid
const url =
"https://weatherkit.apple.com/api/v1/weather/en/51.677612/-2.937941?dataSets=currentWeather&timezone=Europe/London";
const config = {
headers: { Authorization: `Bearer ${token}` },
};
const { data: weatherData } = await axios.get(url, config);
Getting the id on the header is the trick.
I have made a YouTube video and example app but it won't let me post the link, the youtube video id is: 7mg42_Fix9k