CS2 API documentation.
The CS2 API is REST JSON at https://api.citoapi.com/api/v1, with CS2 routes under /cs2. Authenticate with an x-api-key header. Every response has success and data, lists add meta for paging, and errors return a code, a message and a docs link.
- REST JSON
- x-api-key header
- 500 free requests / month
{ "success": true, "data": { "name": "Counter-Strike 2 API", "coverage": { "matches": 15000, "teams": 4498, "players": 8801, "events": 1521 } }}CS2 API in numbers
Measured on production, with the date each figure was taken.
- The CS2 API answered 197,791 requests in the 24 hours to 3 October 2026 with a median server response time of 227 ms.
- 99.996% of CS2 API requests in the 24 hours to 3 October 2026 completed without a server error (7 errors in 197,791 requests).
- Live CS2 match data on the CS2 API refreshes every 15 seconds at the median, measured over 22,479 live sync runs in the 7 days to 3 October 2026.
- Every CS2 API plan can open the Server-Sent Events stream at /api/v1/cs2/live/stream; it counts one request at connect and one per 15 seconds open.
How do I make my first request?
Get a free key at citoapi.com, then send it in the x-api-key header to any /cs2 route. GET /cs2 returns what the API covers; GET /cs2/matches/live returns matches in progress.
curl -s "https://api.citoapi.com/api/v1/cs2/matches/live" -H "x-api-key: $CITO_API_KEY"import os, requests
r = requests.get("https://api.citoapi.com/api/v1/cs2/matches/live",
headers={"x-api-key": os.environ["CITO_API_KEY"]}, timeout=10)
r.raise_for_status()
for m in r.json()["data"]:
print(m["team1Name"], m["team1Score"], "-", m["team2Score"], m["team2Name"])const res = await fetch("https://api.citoapi.com/api/v1/cs2/matches/live", {
headers: { "x-api-key": process.env.CITO_API_KEY },
})
const { data } = await res.json()
for (const m of data) console.log(m.team1Name, m.team1Score, "-", m.team2Score, m.team2Name)How does authentication work?
Send the key in the x-api-key header on every request; Authorization: Bearer <key> also works. Keys start with cito_ and are 69 characters long. Keep the key on a server: the API does not allow browser calls from other origins.
What does a response look like?
Successful responses are { success: true, data, meta }. Lists put paging in meta: page, limit, total, totalPages, hasNext and hasPrev. Pass page and limit to move through results.
{
"success": true,
"data": [
{
"rank": 1,
"teamName": "Spirit",
"points": 1000,
"change": 0
},
{
"rank": 2,
"teamName": "Vitality",
"points": 676,
"change": 0
}
],
"meta": {
"page": 1,
"limit": 2,
"total": 251,
"hasNext": true,
"ranking": "world",
"rankingDate": "2026-10-03"
}
}What do errors look like?
Errors return { success: false, error: { code, message, status, docs } } with a matching HTTP status. The code is stable and safe to branch on; the message is for people.
| Status | Code | Meaning |
|---|---|---|
| 401 | MISSING_API_KEY | No x-api-key header. |
| 401 | INVALID_API_KEY | Malformed, unknown, revoked or expired key. |
| 403 | WEBSOCKETS_REQUIRED | WebSocket upgrade on a plan without CS2 WebSockets. |
| 404 | – | No such route or entity; the body names what was not found. |
| 429 | – | Plan limit reached; Retry-After says when to try again. |
What are the rate limits?
Limits are per plan: 10 requests a minute and 500 a month on Free, up to 400 a minute and 1,000,000 a month on Scale. Responses carry X-RateLimit-Remaining; a 429 adds Retry-After, X-RateLimit-Limit and X-RateLimit-Reset.
How do IDs and slugs work?
Every match, map, team, player and event has a stable ID such as cs2-match-2398722 or cs2-team-9565. Teams, players and events also accept a readable slug, so /cs2/teams/vitality and /cs2/players/zywoo work as well as their IDs.
How do I get live updates?
Four ways, from simplest to most real-time: poll GET /cs2/matches/live, keep the SSE stream at /cs2/live/stream open (every plan), open the WebSocket at /cs2/live/ws (Scale, or Pro with the add-on), or receive webhooks (Pro and Scale).
| Transport | Plans | Billing |
|---|---|---|
| Polling REST | All | One request per call |
| SSE /cs2/live/stream | All | One at connect, one per 15 s open |
| WebSocket /cs2/live/ws | Scale, Enterprise; Pro with add-on | Included |
| Webhooks | Pro, Scale | Included |
Where is the full endpoint reference?
The CS2 API endpoints page lists every route grouped by job, and the complete reference with parameters lives on citoapi.com/docs/api/cs2. AI agents can use the Cito MCP server: npx cito-mcp install.
Frequently asked questions
Something missing? Email support@citoapi.com.
What is the CS2 API base URL?
https://api.citoapi.com/api/v1. CS2 routes start with /cs2, for example /cs2/matches/live.
How do I authenticate with the CS2 API?
Send your key in the x-api-key header (or Authorization: Bearer). Keys start with cito_.
Does the CS2 API have an OpenAPI spec?
Yes. The CS2 reference on citoapi.com is generated from an OpenAPI document, so you can generate a typed client from it.
Can AI coding agents read these docs?
Yes. cs2-api.org/llms.txt lists every page, cs2-api.org/llms-full.txt carries every FAQ, and all docs pages are plain HTML with complete code.
Reference and guides
- CS2 API endpointsEvery CS2 endpoint on one page, grouped by job.
- CS2 API tutorialsStep-by-step guides with complete, runnable code.
- CS2 API errorsExact error messages, why they happen and the fix, with code.
- CS2 API pricingFree, Starter, Pro and Scale: requests, live delay and history per plan.
- CS2 API in PythonLive scores, results and player stats with requests.
- CS2 API in Node.jsFetch CS2 data from JavaScript and TypeScript.
Build CS2 live score apps
Free is for building and testing. Paid plans add commercial use, real-time live data and the full archive.