Skip to content

Instantly share code, notes, and snippets.

@petersvp
Created February 3, 2021 20:30
Show Gist options
  • Save petersvp/270f7d5d7d548448f4897586a0d389c0 to your computer and use it in GitHub Desktop.
Save petersvp/270f7d5d7d548448f4897586a0d389c0 to your computer and use it in GitHub Desktop.
Batch Query Steam Keys for activation on SteamWorks
// 1. GO TO SteamWorks, into the Query CD Key page, here: https://partner.steamgames.com/querycdkey/
// 2. Fill in your keys below:
// 3. Go to DevTools, Console, and paste all of this here there!
// 4. Report will be printed to the console.
keys = `
0ZQR4-N0H7K-AEJ77
D05V5-P47AP-4ET3Q
GGJZ5-ZN0BR-F74C5
FWZP4-2IXHB-GYV3A
`
var keylist = keys.split("\n");
keylist.forEach(key => {
if(key.length<17) return;
function reqListener () {
let body = this.responseText;
let result = body.split('<h2>Activation Details</h2>')[1];
if (!result && !err) {
console.log('Error quering CD Key ' + key);
}
result = result.split('</table>')[0];
result = result.match(/<td>.*<\/td>/g);
result = result.map(function (line) {
return line.replace(/<[^>]*>/g, '');
});
let line = [key, (result[0] === 'Activated') ? '"' + result[1] + '"' : result[0]].join('\t');
console.log(line);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "https://partner.steamgames.com/querycdkey/cdkey?cdkey="+key+"&method=Query");
oReq.send();
});
@Jimbly
Copy link

Jimbly commented Feb 10, 2022

Yeah, a couple hundred keys should be fine in the browser, it's not that much traffic. Also, most browsers usually rate limit to 7 connections per host, although in modern days if Valve has switched to a load balancer/server that supports HTTP2 that goes out the window. If you're querying thousands of keys I might be a little careful =).

@petersvp
Copy link
Author

Chrome does rate-limit too, I managed to batch-check 500 keys with no issue. I want to keep this implementation as CLEAN as possible, so people can read what it do and not fear of self-xss attack towards them - after all, pasting untrusted code in the browser console is real concern nowadays, so i at least tried to make my implementation clear what it does :)

@tcurtis526
Copy link

Appreciate this.

@Goury
Copy link

Goury commented Jul 22, 2024

I was about to code a better snippet based on this, but decided that this one is good enough.
Thanks.

The only issue is that it won't find <h2>Activation Details</h2> if your language is set to anything other than English.

@petersvp
Copy link
Author

petersvp commented Oct 10, 2024

I was about to code a better snippet based on this, but decided that this one is good enough. Thanks.

The only issue is that it won't find <h2>Activation Details</h2> if your language is set to anything other than English.

Just change the text to whatever your language is, or add ?hl=en to the query string. This code is written in such a way that a human being should be able to quickly verify what the script is all about and you have to edit the script anyways to feed in your keys.

@AumCoin
Copy link

AumCoin commented Jan 27, 2025

Do I need to be signed up as a developer and have a paid developer account? Will this work with any key or just keys for my own games?

@petersvp
Copy link
Author

Yes, and the developer account must have access to the game you are querying too.

@hydrok
Copy link

hydrok commented Mar 20, 2025

If you need to add a delay for the purpose of rate limiting each request, try this code. I wrapped the original code in a setTimeout() and var interval is the amount of time (in ms) to delay. Thanks again for this solution!


keys = `
0ZQR4-N0H7K-AEJ77
D05V5-P47AP-4ET3Q
GGJZ5-ZN0BR-F74C5
FWZP4-2IXHB-GYV3A
`

    var keylist = keys.split("\n");
	var interval = 1000;

keylist.forEach((key, i) => {
	setTimeout(() => {	
		if (key.length < 17)
			return;
		function reqListener() {
			let body = this.responseText;
			let result = body.split('<h2>Activation Details</h2>')[1];
			if (!result && !err) {
				console.log('Error quering CD Key ' + key);
			}
			result = result.split('</table>')[0];
			result = result.match(/<td>.*<\/td>/g);
			result = result.map(function (line) {
				return line.replace(/<[^>]*>/g, '');
			});
			let line = [key, (result[0] === 'Activated') ? '"' + result[1] + '"' : result[0]].join('\t');
			console.log(line);
		}
		var oReq = new XMLHttpRequest();
		oReq.addEventListener("load", reqListener);
		oReq.open("GET", "https://partner.steamgames.com/querycdkey/cdkey?cdkey=" + key + "&method=Query");
		oReq.send();
	}, i * interval);
});

@petersvp
Copy link
Author

petersvp commented Mar 20, 2025 via email

@bfmmdev
Copy link

bfmmdev commented Apr 7, 2025

Getting errors expecting expecting semicolon before error.

What am I doing wrong?

EDIT: Clear console totally before running the script. Yes, this includes deleting the precurors "allow pasting" and all that.

@Goury
Copy link

Goury commented Apr 7, 2025

What am I doing wrong?

Not telling us the exact and whole error

@bfmmdev
Copy link

bfmmdev commented Apr 7, 2025

Doesn't matter what the issue is because I posted the solution for the issue I was running into. TLDR; ensure the console is completely empty before running the script.

@ThomazDiniz
Copy link

Just wanted to say thank you, I've used your code to make one that returns a list of not yet used keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment