I looked in network developer tools and found the request for projects.scratch.mit.edu now needs token specifically the one from the metadata. With some very simple code this issue can be fixed:
with open(f"{project_id}.json") as f:
json_stuff = json.loads(f.read())
print(f"Downloading project {project_id}")
r = requests.get(f"https://projects.scratch.mit.edu/{project_id}?token={json_stuff['project_token']}", headers=headers)
I looked in network developer tools and found the request for projects.scratch.mit.edu now needs token specifically the one from the metadata. With some very simple code this issue can be fixed: