ErrorCS2 API errors

CS2 share code decode failed: the fix.

A CS2 match share code is CSGO- plus 25 characters from a 57-character alphabet. Decode it by reversing the characters, reading them as a base-57 number, writing that as 18 bytes, and reading the match ID, reservation ID and TV port little-endian. Most failures are the wrong alphabet or byte order.

  • 57-character alphabet
  • 18 bytes, little-endian
  • Tested decoders
GET /cs2/matches/results?limit=2200 OK
$ curl "https://api.citoapi.com/api/v1/cs2/matches/results?limit=2" \ -H "x-api-key: $CITO_API_KEY"
{  "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 }    }    ...  ]}

The error

What you see
InvalidShareCode: Invalid share code        (csgo-sharecode, npm)
ValueError: not a match share code: '...'    (Python decoders)
or: the code decodes, but the match ID points at nothing

What is the CS2 share code format?

CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx: five groups of five characters from the alphabet ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789. It leaves out I, O, g, l and the digits 0 and 1, which look alike. CS2 match codes still start with CSGO-.

Why does decoding fail?

Almost every broken decoder makes one of the mistakes below. The result is either an exception or a match ID that looks valid but points at nothing.

  • A 62- or 64-character alphabet instead of the 57-character one.
  • Not reversing the 25 characters before the base-57 conversion.
  • Not left-padding the hex to 36 digits (18 bytes), which shifts every field.
  • Reading the fields big-endian; each field is little-endian.
  • Using 32-bit or float arithmetic: the number needs arbitrary precision (Python int, JavaScript BigInt).
  • Passing a crosshair or other share code: only match codes decode to a match.

How do I decode a share code correctly?

Use the decoders below. Both are tested: CSGO-GADqf-jjyJ8-cSP2r-smZRo-TO2xK decodes to match ID 3230642215713767580, reservation ID 3230647599455273103 and TV port 55788, matching the reference implementation (akiver/csgo-sharecode).

Python 3
import re

DICTIONARY = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789"
SHARE_CODE = re.compile(r"^CSGO(-?[" + DICTIONARY + r"]{5}){5}$")

def decode_share_code(code: str) -> dict:
    code = code.strip()
    if not SHARE_CODE.match(code):
        raise ValueError(f"not a match share code: {code!r}")
    big = 0
    for c in reversed(code[4:].replace("-", "")):
        big = big * len(DICTIONARY) + DICTIONARY.index(c)
    raw = big.to_bytes(18, "big")
    return {
        "matchId": int.from_bytes(raw[0:8], "little"),
        "reservationId": int.from_bytes(raw[8:16], "little"),
        "tvPort": int.from_bytes(raw[16:18], "little"),
    }

print(decode_share_code("CSGO-GADqf-jjyJ8-cSP2r-smZRo-TO2xK"))
# {'matchId': 3230642215713767580, 'reservationId': 3230647599455273103, 'tvPort': 55788}
JavaScript (Node.js or browser, BigInt)
const DICTIONARY = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789"
const SHARE_CODE = new RegExp(`^CSGO(-?[${DICTIONARY}]{5}){5}$`)

export function decodeShareCode(code) {
  code = code.trim()
  if (!SHARE_CODE.test(code)) throw new Error(`not a match share code: ${code}`)
  let big = 0n
  for (const c of [...code.slice(4).replaceAll("-", "")].reverse()) big = big * 57n + BigInt(DICTIONARY.indexOf(c))
  const bytes = big.toString(16).padStart(36, "0").match(/../g).map((h) => parseInt(h, 16))
  const le = (from, to) => bytes.slice(from, to).reverse().reduce((acc, b) => (acc << 8n) | BigInt(b), 0n)
  return { matchId: le(0, 8), reservationId: le(8, 16), tvPort: Number(le(16, 18)) }
}

What can I do with the decoded IDs?

The match ID and reservation ID identify the replay, which a Steam client library can request from Valve's game coordinator to get the demo URL. The decoded values contain no scores or stats; those come from parsing the demo.

How does the CS2 API make this error impossible?

Pro matches have stable IDs such as cs2-match-2398722 that you read straight from the API, so there is no share code to decode at all. Share codes only matter for a player's own matchmaking games, which only Steam has.

One request instead of the whole Steam chain
curl -s "https://api.citoapi.com/api/v1/cs2/matches/results?limit=5" -H "x-api-key: $CITO_API_KEY"

Frequently asked questions

Something missing? Email support@citoapi.com.

What alphabet do CS2 share codes use?

ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789: 57 characters, without I, O, g, l, 0 and 1.

What does a CS2 share code decode to?

Three numbers: the match ID (8 bytes), the reservation or outcome ID (8 bytes) and the TV port (2 bytes), each little-endian.

Do CS2 match share codes still start with CSGO-?

Yes. Match share codes kept the CSGO- prefix after the move to Counter-Strike 2.

See pricing

Build CS2 live score apps

Free is for building and testing. Paid plans add commercial use, real-time live data and the full archive.