HLTVEvery HLTV API guide

The CS2 team ranking, as an API.

HLTV shows its team ranking on a web page and offers no API for it. To use a CS2 ranking in code, call GET /cs2/rankings/world for the world ranking (rank, points and weekly change for 250 teams) or GET /cs2/rankings/vrs for Valve's Regional Standings. A free key covers 500 requests a month.

  • World ranking + VRS
  • Weekly change per team
  • 500 free requests / month
GET /cs2/rankings/world?limit=3200 OK
$ curl "https://api.citoapi.com/api/v1/cs2/rankings/world?limit=3" \ -H "x-api-key: $CITO_API_KEY"
{  "success": true,  "meta": {    "ranking": "world",    "rankingDate": "2026-10-12"  },  "data": [    {      "rank": 1,      "teamName": "Spirit",      "points": 1000    },    {      "rank": 2,      "teamName": "Vitality",      "points": 686    },    {      "rank": 3,      "teamName": "MOUZ",      "points": 562    },    "__more__"  ]}

Seamless Integration with our MCP Server

Give Claude, Cursor, and ChatGPT the CS2 data. One command writes the MCP config; agents call live scoreboard, team map stat, opening duel, and transfer tools instead of inventing match IDs, and your key stays on your machine.

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

What does the world ranking look like right now?

The table is GET /cs2/rankings/world at build time: the same rows, points and movement your code receives, so a ranking widget on your site can match it exactly.

Top 10 of the world ranking (250 teams) from GET /cs2/teams/rankings, ranking date 2026-10-12. Fetched from the production CS2 API on 12 Oct 2026, 13:15 UTC.
RankTeamPointsChangeRegion
1Spirit1,000–Europe
2Vitality686–Europe
3MOUZ562–Europe
4FURIA534–South America
5Falcons496–Europe
6Legacy430–South America
7G2384–Europe
8FUT359–Europe
9Aurora350–Europe
10Natus Vincere241–Europe

World ranking or VRS: which one do I need?

Use the world ranking for the familiar top-30 style table fans follow week to week. Use VRS when you need the ranking Valve itself uses for Major and tournament invitations. Both come with the same row shape, so one parser handles either.

World rankingValve Regional Standings (VRS)
EndpointGET /cs2/rankings/worldGET /cs2/rankings/vrs
Teams250350
Row fieldsrank, teamName, points, change, regionrank, teamName, points, change, region
Movementchange since meta.changeSincechange since meta.changeSince
Typical useRanking tables, bots, power rankingsInvite tracking, Major qualification

What does VRS look like right now?

GET /cs2/rankings/vrs at build time, top 10 with points and movement.

Top 10 of the Valve Regional Standings (349 teams) from GET /cs2/rankings/vrs, ranking date 2026-10-12. Fetched from the production CS2 API on 12 Oct 2026, 13:15 UTC.
RankTeamPointsChangeRegion
1Vitality1,978▲2Europe
2MOUZ1,946▲2Europe
3Spirit1,940▼2Europe
4Falcons1,843▲2Europe
5Aurora1,840▲4Europe
6Legacy1,792▼4South America
7FURIA1,784–South America
8G21,721▼3Europe
9FUT1,703▼1Europe
10Astralis1,607–Europe

How do I fetch the ranking in Python or Node.js?

One GET returns the ranking newest first, paged with page and limit. meta.rankingDate says which week you have, so you only redraw a table when that date changes.

Python: top 30 with movement
import os, requests

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

r = requests.get(f"{API}/rankings/world", headers=H, params={"limit": 30}, timeout=10)
r.raise_for_status()
body = r.json()
print("Ranking of", body["meta"]["rankingDate"])
for t in body["data"]:
    change = t["change"] or 0
    move = f"+{change}" if change > 0 else str(change) if change < 0 else "="
    print(f"{t['rank']:>2}. {t['teamName']:<20} {t['points']:>5} pts  {move}")
Node.js 18+: biggest movers in VRS
const res = await fetch("https://api.citoapi.com/api/v1/cs2/rankings/vrs?limit=100", {
  headers: { "x-api-key": process.env.CITO_API_KEY },
})
const { data, meta } = await res.json()
const movers = data.filter((t) => t.change).sort((a, b) => Math.abs(b.change) - Math.abs(a.change))
console.log(`VRS ${meta.rankingDate}, change since ${meta.changeSince}`)
for (const t of movers.slice(0, 5)) console.log(t.rank, t.teamName, t.change > 0 ? `+${t.change}` : t.change)

How fresh is the ranking?

The world ranking moves weekly. Every response carries meta.rankingDate (the ranking you have), meta.changeSince (the ranking change is measured against) and syncedAt (when the API last checked), so you can show the date next to the table and only redraw when it changes.

How much CS2 data is behind it?

Measured on production, with the date each figure was taken.

  • The CS2 API serves the world ranking (250 teams) and the Valve Regional Standings (349 teams), updated 12 October 2026.
  • The CS2 API indexes 15,315 Counter-Strike 2 matches, 4,507 teams and 8,828 players across 1,534 tournaments (as of 12 October 2026).
  • The CS2 API answered 197,791 requests in the 24 hours to 3 October 2026 with a median server response time of 227 ms.
  • The free CS2 API plan includes 500 requests a month, 10 requests a minute and live data on a 60-second delay, with no credit card.

Endpoints you can ship with

Start on rankings: the world ranking, VRS and one region.

Rankings

The world team ranking and the Valve Regional Standings, with points and movement, plus one table per region.

View docs
  • GET/api/v1/cs2/rankings/world

    The latest world team ranking.

  • GET/api/v1/cs2/rankings/vrs

    The latest Valve Regional Standings (VRS).

  • GET/api/v1/cs2/rankings/region/{region}

    One region, with each team's world and regional rank.

  • GET/api/v1/cs2/rankings

    One row per team, with points and change since the previous ranking.

FAQs

Rankings, VRS and movement

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

Read the CS2 docs

Build ranking tables

Create a free key and pull the ranking in one call.