PythonCopy-paste examples below

CS2 data in Python, in ten lines.

Plain HTTPS and JSON, so requests is all you need: one helper, then live scores, results and a player's form. Paste the key into CITO_API_KEY and run.

  • requests only
  • JSON in, dicts out
  • 500 free requests / month
GET /cs2/live200 OK
$ curl "https://api.citoapi.com/api/v1/cs2/live" \ -H "x-api-key: $CITO_API_KEY"
{  "data": [    ...    {      "team1Name": "Iberian Soul",      "team2Name": "Butterfly",      "score": { "team1": 0, "team2": 0 },      "currentMap": "de_mirage",      "currentMapScore": { "team1": 5, "team2": 13 },      "currentRound": 18    }  ]}

Seamless Integration with our MCP Server

Prefer an assistant writing the Python? One command gives Claude or Cursor the CS2 tools, so the code it writes calls real endpoints with real IDs.

MCPInstall the Cito MCP server
Claude
Cursor
OpenAI
Python
Cito API
Next.js
Discord
Slack
GitHub

What Python projects build

The usual first scripts, each a single call.

Live tickers

Print or push every match in progress.

Result feeds

Recent results into a database or a post.

Player models

Per-map stats into pandas for analysis.

Rankings snapshots

Store the VRS table every week.

Schedulers

Upcoming matches into reminders and calendars.

Notebooks

Explore the API in Jupyter with one helper.

Replacing an HLTV scraper in Python?

Python HLTV libraries scrape hltv.org, which now answers scripts with a Cloudflare 403. The HLTV API in Python guide swaps each scraper call for one of these endpoints.

Live scores in Python

Set CITO_API_KEY in your environment, then run.

live.py
import os
import requests

API = "https://api.citoapi.com/api/v1"
HEADERS = {"x-api-key": os.environ["CITO_API_KEY"]}


def get(path, **params):
    r = requests.get(f"{API}{path}", headers=HEADERS, params=params, timeout=10)
    r.raise_for_status()
    return r.json()


# Every CS2 match in progress
for m in get("/cs2/live")["data"]:
    ms = m.get("currentMapScore") or {}
    print(f'{m["team1Name"]} {m["team1Score"]}-{m["team2Score"]} {m["team2Name"]} | '
          f'{m["currentMap"]} {ms.get("team1", 0)}-{ms.get("team2", 0)}, round {m["currentRound"]}')

Results and player stats

The same helper, two more endpoints.

stats.py
# Last five results
for m in get("/cs2/matches/recent", limit=5)["data"]:
    print(f'{m["eventName"]}: {m["team1Name"]} {m["team1Score"]}-{m["team2Score"]} {m["team2Name"]}')

# ZywOo's recent maps
for row in get("/cs2/players/zywoo/form", limit=5)["data"]:
    print(row["map"]["mapName"], row["kills"], row["deaths"], row["adr"], row["rating"])

Endpoints you can ship with

Every route here works from requests.get.

Live matches

Poll the live list for every match in progress, open one match for its round, timer, bomb and players, or keep an SSE stream open and get each update pushed.

View docs
  • GET/api/v1/cs2/live

    Matches in progress: series score, map in play, map score, current round.

  • GET/api/v1/cs2/live/{matchId}/state

    One live match: score, round, round timer, bomb status and players.

  • GET/api/v1/cs2/live/{matchId}/scoreboard

    Series score, current map and round, and each player's kills, deaths, money and equipment.

  • GET/api/v1/cs2/live/{matchId}/rounds

    Round-by-round results so far: winner, side and how each round ended.

  • GET/api/v1/cs2/live/stream

    Server-Sent Events push of every live update. Every plan; counts like polling.

  • GET/api/v1/cs2/live/ws

    WebSocket with a room per match. Scale and Enterprise; Pro with the Live WebSockets add-on.

Frequently asked questions

Python setup, auth and paging

Something missing? Email support@citoapi.com.

Is there a Python library for the CS2 API?

You do not need one: it is REST and JSON, so requests (or httpx) and a small helper cover every endpoint.

How do I authenticate from Python?

Send the key in the x-api-key header, for example headers={'x-api-key': os.environ['CITO_API_KEY']}.

How do I page through results?

Pass limit and page as query parameters and read meta.hasNext to know when to stop.

Can I load the data into pandas?

Yes. pandas.json_normalize(response['data']) flattens a list response into a DataFrame.

Is this an HLTV Python API alternative?

Yes. It covers results, ratings, rankings and live scores without scraping.

See pricing

Build in Python: live tickers

Get a free key and run the first example.