You need to get a "badger token". I haven't found documentation on it anywhere.
Here's complete working code. It uses "createLink" to create a link, shows how to base64 encode the webUrl (or you can just use shareId that's returned from createLink). And it shows how to get the direct link.
I learned this from https://github.com/felixrieseberg/onedrive-link/issues/1 and https://github.com/rclone/rclone/issues/7898
// Get driveId. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/drive_get
const driveResponse = await fetch(`https://api.onedrive.com/v1.0/drive?access_token=${accessToken}`)
const driveId = (await driveResponse.json()).id;
// Get Music folder id. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/drive_get_specialfolder
const musicResponse = await fetch(`https://api.onedrive.com/v1.0/drives/${driveId}/special/music?access_token=${accessToken}`)
const musicId = (await musicResponse.json()).id;
// Create Music/MyFolder1. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_post_children
const createBody = { name: "MyFolder1", folder: {}, "@microsoft.graph.conflictBehavior": "replace" };
const createResponse = await fetch(`https://api.onedrive.com/v1.0/drives/${driveId}/items/${musicId}/children?access_token=${accessToken}`, { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(createBody) });
const folderId = (await createResponse.json()).id;
// Upload Music/MyFolder1/foo.txt. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content
const fileResponse = await fetch(`https://api.onedrive.com/v1.0/drives/${driveId}/items/${folderId}:/foo.txt:/content?access_token=${accessToken}`, { method: "PUT", headers: { 'Content-Type': 'textplain' }, body: "hello world\n" });
const fileId = (await fileResponse.json()).id;
// Share Music/MyFolder1. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink
// The docs for "direct endpoint" above say that we must use a namespace prefix for the createLink action.
// The docs don't actually tell us what that namespace-prefix is, but I discovered that "action.createLink" works.
const linkBody = { type: "view", scope: "anonymous" };
const linkResponse = await fetch(`https://api.onedrive.com/v1.0/drives/${driveId}/items/${folderId}/action.createLink?access_token=${accessToken}`, { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(linkBody) });
const link = await linkResponse.json();
const shareId = link.shareId;
const webUrl = link.link.webUrl;
assert(link.link.scope === "anonymous");
assert(link.link.type === "view");
assert(shareId === 'u!' + btoa(webUrl).replace(/=*$/, '').replace('/', '_').replace('+', '-')); // as per https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get
// We'll want a direct-download link to the shareId. But this needs a "badger token", whatever that is...
// The appId is hard-coded and universal; I presume it's some Microsoft central service?
// The badgerResponse I've seen so far all indicate an expiry date for the token that's one week out.
const badgerBody = { appId: '5cbed6ac-a083-4e14-b191-b4ba07653de2' };
const badgerResponse = await fetch('https://api-badgerp.svc.ms/v1.0/token', { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(badgerBody) });
const badgerToken = (await badgerResponse.json()).token;
// Get the shared item. https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get
const getResponse = await fetch(`https://api.onedrive.com/v1.0/shares/${shareId}/driveItem?$expand=children`, { method: "GET", headers: { "Authorization": `Badger ${badgerToken}`, "Prefer": "autoredeem" } });
console.log(await getResponse.text());
// There's another way to get the shared item, by turning the webUrl into a redeem code...
const redirectResponse = await fetch(webUrl, { redirect: "manual" });
assert(redirectResponse.status === 301);
const redirectParams = new URLSearchParams(new URL(redirectResponse.headers.get('location') || '').search);
const redeem = redirectParams.get('redeem') || '';
const getResponse2 = await fetch(`https://api.onedrive.com/v1.0/shares/u!${redeem}/driveItem?$expand=children`, { method: "GET", headers: { "Authorization": `Badger ${badgerToken}`, "Prefer": "autoredeem" } });
console.log(await getResponse2.text());