The Steam Web API for CS2, step by step.
Steam's Web API can give a CS2 app one thing about matches: the share codes of one account's own matchmaking games, one at a time, with that player's game authentication code. It has no scores, no player stats and no pro matches. This guide does the share-code walk end to end, then shows where you switch.
- Own games only
- Share codes, not stats
- 100,000 calls / day
{ "success": true, "data": [ { "id": "cs2-match-2398974", "eventName": "ROG JOURNEY Autumn 2026", "bestOf": 3, "team1Name": "Ninjas in Pyjamas", "team2Name": "Eternal Fire", "score": { "team1": 2, "team2": 0 } }, { "id": "cs2-match-2398896", "eventName": "FOX Legacy Season 1", "bestOf": 3, "team1Name": "SAW", "team2Name": "Lazer Cats", "score": { "team1": 2, "team2": 0 } } ... ]}Step 1: How do I get a Steam Web API key?
Sign in at steamcommunity.com/dev/apikey with a Steam account in good standing, enter a domain name, and Steam issues a 32-character key. Keep it on a server: Valve's terms require it to stay confidential, and Steam sends no CORS headers, so browsers cannot call the API anyway.
Step 2: What does the player have to give me?
Three things: their 64-bit Steam ID, a game authentication code they create in Steam's help pages for CS2 match history, and the share code of one match they already played. Without the authentication code Steam will not hand out their match codes.
- Steam ID (64-bit), for example 76561197960287930.
- Game authentication code, format AAAA-AAAAA-AAAA. Treat it like a password.
- A known share code, format CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx, copied from the in-game match history.
Step 3: How do I list the player's matches?
Call ICSGOPlayers_730/GetNextMatchSharingCode with the known code. It returns the next code; call again with that one, and stop when it returns "n/a". Store the last code you saw, so the next run starts from there instead of from the beginning.
import json, pathlib, requests
STEAM_KEY = "YOUR_STEAM_WEB_API_KEY"
URL = "https://api.steampowered.com/ICSGOPlayers_730/GetNextMatchSharingCode/v1/"
STATE = pathlib.Path("last_code.json")
def new_share_codes(steamid: str, auth_code: str, first_known: str) -> list[str]:
code = json.loads(STATE.read_text())["code"] if STATE.exists() else first_known
found = []
while True:
r = requests.get(URL, params={"key": STEAM_KEY, "steamid": steamid,
"steamidkey": auth_code, "knowncode": code}, timeout=10)
if r.status_code == 202: # some clients see this for "nothing newer yet"
break
r.raise_for_status() # 403: check the key and the auth code
nxt = r.json()["result"]["nextcode"]
if nxt == "n/a":
break
found.append(nxt)
code = nxt
STATE.write_text(json.dumps({"code": code}))
return found
print(new_share_codes("7656119...", "AAAA-AAAAA-AAAA", "CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"))Step 4: How do I turn a share code into a match ID?
Decode it: the 25 characters after CSGO- are a base-57 number that holds the match ID, the reservation ID and the TV port. The share code decode page has tested Python and JavaScript decoders and the five mistakes that break them.
Step 5: Where does the Steam Web API stop?
Right there. No Steam Web API method returns the scoreboard for a match ID: kills, rounds and ratings come from downloading the replay demo through a Steam client library and parsing it. And professional matches are not in Steam at all, so none of this works for esports.
| You want | Steam Web API | What to use |
|---|---|---|
| Your own match list | Share codes, one per call | Steam (this guide) |
| Your own match stats | No | Replay demo + a parser such as demoparser2 |
| Pro results and maps | No | CS2 API: /cs2/matches/results |
| Pro player ratings | No | CS2 API: /cs2/players/{slug}/matches |
| Live pro scores | No | CS2 API: /cs2/matches/live |
| Rankings, VRS | No | CS2 API: /cs2/rankings/vrs |
How does the CS2 API fill the gap?
For professional CS2 it replaces the whole chain: no auth codes, share codes, demos or parsers. One key, one request per job, and the stats are already per map.
import os, requests
H = {"x-api-key": os.environ["CITO_API_KEY"]}
match = requests.get("https://api.citoapi.com/api/v1/cs2/matches/results", params={"limit": 1}, headers=H).json()["data"][0]
lines = requests.get(f"https://api.citoapi.com/api/v1/cs2/matches/{match['id']}/player-stats", headers=H).json()["data"]
for p in lines:
print(p["playerName"], p["kills"], p["deaths"], p["adr"], p["rating"])Frequently asked questions
Something missing? Email support@citoapi.com.
Can the Steam Web API return CS2 match stats?
No. It returns share codes for an account's own matchmaking games; kills, rounds and ratings come from the replay demo. Pro match stats are not in Steam at all.
What is a CS2 game authentication code?
A code the player creates in Steam's help pages that lets an app read their match share codes through GetNextMatchSharingCode. It is passed as steamidkey.
What is the Steam Web API limit for CS2 apps?
100,000 calls per key per day under the Steam Web API Terms of Use, with 429 Too Many Requests when throttled.
Did Valve deprecate CS2 match history in the Steam API?
There was never a public CS2 or CS:GO GetMatchHistory endpoint; it only exists for Dota 2. The share-code method in this guide is the only match-history route Steam offers for CS2.
Related
- Steam CS2 APIWhat Valve's Steam Web API covers for CS2, and the match-data gap.
- CS2 share code decode failedThe share code alphabet, the decode algorithm and the usual mistakes.
- CS2 match history not foundThere is no Steam match history endpoint for CS2. What to call instead.
- How to get CS2 match dataResults, maps and player lines for any pro match in three requests.
- CS2 match results APIFinal series scores, map scores and box scores.
- Steam API 403 ForbiddenBad key, wrong auth code or a private profile: find which one.
Build CS2 live score apps
Free is for building and testing. Paid plans add commercial use, real-time live data and the full archive.