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.

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.

FAQs

Python setup, auth and paging

Can't find what you're looking for? Contact our customer support team

See pricing

Build in Python: live tickers

Get a free key and run the first example.