Skip to content

Instantly share code, notes, and snippets.

@ssaki
Created March 27, 2026 20:05
Show Gist options
  • Select an option

  • Save ssaki/aa6181fb37fba8b19dcf81f18dc50ee3 to your computer and use it in GitHub Desktop.

Select an option

Save ssaki/aa6181fb37fba8b19dcf81f18dc50ee3 to your computer and use it in GitHub Desktop.
Print a list of all creations in your Starfield library
/**
* This script will make a text table of all creation in your library - name and author
*
* 1. Go to https://creations.bethesda.net/en/starfield/library and make sure you are logged in!
* 2. Open dev console (F12) and copy/paste this script in it and press enter.
* 3. Force the site to make new request - e.g. change the page
*
* How it works - Once it is started it register a small function to intercept requests and get the key bethesda's site is using to identify you.
* Once it has it - it will pull all pages of creations and will print the tabler in the console.
*/
(async () => {
// Intercept fetch to steal the x-bnet-key from a real request
let BNET_KEY;
const origFetch = window.fetch;
window.fetch = function(...args) {
const [url, opts] = args;
if (opts?.headers) {
// check both Headers object and plain object
if (opts.headers instanceof Headers) {
const k = opts.headers.get('x-bnet-key');
if (k) BNET_KEY = k;
} else if (typeof opts.headers === 'object') {
const k = opts.headers['x-bnet-key'];
if (k) BNET_KEY = k;
}
}
return origFetch.apply(this, args);
};
// Also patch XHR
const origOpen = XMLHttpRequest.prototype.open;
const origSetHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
if (name.toLowerCase() === 'x-bnet-key') BNET_KEY = value;
return origSetHeader.call(this, name, value);
};
console.log('Interceptors set. Waiting for a page request to capture the key...');
console.log('Scroll down or click something on the page to trigger an API call.');
// Wait for the key to appear (up to 15s)
for (let i = 0; i < 30; i++) {
if (BNET_KEY) break;
await new Promise(r => setTimeout(r, 500));
}
// Restore originals
window.fetch = origFetch;
XMLHttpRequest.prototype.setRequestHeader = origSetHeader;
if (!BNET_KEY) { console.error('No key captured. Try scrolling/clicking the page and run again.'); return; }
console.log('Captured key:', BNET_KEY);
const TOKEN = document.cookie.match(/bwa-token=([^;]+)/)?.[1];
if (!TOKEN) { console.error('No bwa-token cookie found'); return; }
const headers = {
'authorization': `Bearer ${TOKEN}`,
'x-bnet-product': 'GENESIS',
'x-bnet-key': BNET_KEY,
'content-type': 'application/json'
};
const all = [];
let page = 1, totalPages = Infinity;
while (page <= totalPages) {
const res = await fetch(`https://api.bethesda.net/ugcmods/v2/content/subscribe?product=GENESIS&sort=subscriptions&time_period=all_time&size=60&page=${page}`, { headers });
if (!res.ok) { console.error(`Page ${page}: ${res.status}`); break; }
const r = (await res.json()).platform.response;
totalPages = Math.ceil(r.total / r.size);
r.data.forEach(i => all.push({ title: i.title, author: i.author_displayname }));
page++;
}
const max = all.reduce((m, i) => Math.max(m, i.title.length), 0);
console.log(all.map((m, i) => `${String(i+1).padStart(3)} ${m.title.padEnd(max)} ${m.author}`).join('\n'));
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment