Overview
The CSGO Premier API is a read-only JSON API over HTTPS. It serves the same public data you see on the site: seasons, leaderboards, player profiles, per-season player stats, match results and maps.
Base URL
https://public-api.csgopremier.com/v1
- Every endpoint is a
GETand returns JSON (application/json; charset=utf-8). - Field names are
camelCase. Timestamps are ISO 8601 in UTC (2026-11-05T18:30:00Z). - Responses are compressed when you send
Accept-Encoding: gzip. GET /v1/statusandGET /v1/openapi.jsonwork without a key. Everything else needs one.
The API only contains data produced on CSGO Premier itself. It never includes third-party statistics or private account data such as email addresses, payments or IP addresses.
Getting access
API keys are issued per app, after a short review by staff.
- Request access on the Developers page while signed in. Describe what you are building, roughly how many requests you expect and whether you call the API from a server or a browser. This opens a support ticket with your answers.
- Staff review the request. We may ask questions in the ticket. When approved, we set your rate limits and issue a key.
- Reveal your key on the Developers page. It is shown once: copy it straight into your secret store. Only a hash is kept on our side, so nobody, staff included, can show it to you again.
Each app has at most one live key. If you lose it or think it leaked, ask in your ticket and staff issue a new one; the old key stops working immediately. You can't create keys yourself.
On the Developers page you can always see your app's status, limits and the last 14 days of usage, and edit its allowed origins, allowed IPs, name, description and website.
Authentication
Send your key with every request, in either header:
Authorization: Bearer cpk_your_key_here
X-API-Key: cpk_your_key_here
Keys start with cpk_. Never put a key in a URL or query string: URLs end
up in logs, browser history and referrer headers. A request with a key-like
query parameter (key, api_key, apikey, token, access_token)
is refused with 400 bad_request. If you ever sent your key that way, ask
for a new one.
- Keep the key on your server. Store it in an environment variable or a secret manager, never in a repository, a mobile app or public JavaScript.
- Browser apps should call your own backend, which calls this API. If you must call the API straight from a browser, restrict the key to your website's origins (see below) and accept that the key is visible to anyone who opens the developer tools.
- A request without a valid key gets
401 unauthorized. A key whose app is suspended gets403 forbidden.
Allowed origins and IPs
Two allow-lists limit where your key works. Edit both on the Developers page; changes apply within a minute.
Allowed origins apply to browser requests, which carry an Origin header.
A browser request is only accepted when its origin is on the list, so an
empty list means server-side use only: every request with an Origin
header is refused with 403 origin_not_allowed. Server-side requests (no
Origin header) are not affected by this list. Error responses still carry
CORS headers, so your page can read the error.
- Format:
scheme://host[:port], no path and no trailing slash. https://example.commatches only that host.https://*.example.commatches any subdomain (notexample.comitself).- Plain
http://is only accepted forlocalhostand127.0.0.1, for local development. - Up to 20 origins.
Allowed IPs apply to every request. An empty list allows any address; once
it has entries, requests from other addresses get 403 ip_not_allowed. Use single addresses
(203.0.113.10) or CIDR ranges (203.0.113.0/24, IPv4 /8 or narrower,
IPv6 /32 or narrower). Up to 20 entries. This is the strongest protection for
a server-side key: a leaked key is useless from anywhere else.
Origins are a browser safeguard, not authentication: a script can send any
Origin header it likes. Keep the key secret either way.
CORS preflight (OPTIONS) requests are always answered, allowing the
Authorization, X-API-Key and If-None-Match headers and caching the
answer for a day. Requests never use cookies or credentials.
Rate limits and quotas
Every app has three limits, set by staff when the app is approved and shown on the Developers page:
| Limit | What it means | Typical value |
|---|---|---|
| Per minute | Sustained request rate | 60 requests |
| Burst | The most requests you can send at once; the budget refills at the per-minute rate | 30 requests |
| Per day | Total requests per UTC day, reset at 00:00 UTC | 50,000 requests |
Every authenticated response tells you where you stand:
| Header | Meaning |
|---|---|
RateLimit-Limit | Your burst size: the most requests you can send at once |
RateLimit-Remaining | Requests you can make right now |
RateLimit-Reset | Seconds until the full allowance is back |
RateLimit-Policy | The policy in short form, e.g. 60;w=60;burst=30 (60 per 60-second window, burst 30) |
X-Quota-Limit | Requests allowed today (UTC) |
X-Quota-Remaining | Requests left today |
When you go over a limit you get 429 with a Retry-After header (seconds):
rate_limited: too fast. WaitRetry-Afterseconds, then continue.quota_exceeded: the daily quota is used up.Retry-Afterpoints at the next UTC midnight.
Requests that fail authentication are limited per IP address instead, to stop
key guessing. If the service is under heavy load it may answer 503 overloaded with Retry-After; treat it like a 429.
Back off properly. Honor Retry-After. For repeated 429, 503 or
network errors, retry with exponential backoff and jitter (for example 1s, 2s,
4s, 8s, each plus a random 0–1s, capped at 60s), and stop after a few
attempts. Never retry 4xx errors other than 429: they won't succeed.
Need more? Ask in your support ticket with your current usage and why. Limits are per app; creating extra accounts or apps to get around them gets all of them suspended.
Caching
Most data changes slowly. Caching on your side keeps you well inside your limits and makes your app faster.
- Responses carry
Cache-Control: public, max-age=Nsaying how long the data is good for. Typical values: seasons and maps 5 minutes, leaderboards and profiles about a minute, finished matches an hour or more. - Responses carry an
ETag. Send it back asIf-None-Match; if nothing changed you get an empty304 Not Modified, which is cheap for both sides. A304still counts as a request. - Leaderboards and ranks are rebuilt about every 60 seconds. Polling them
more often returns the same data. Each leaderboard response includes
meta.generatedAt. - Finished matches never change: cache them for as long as you like.
- For a bot answering many users, cache each player for at least a minute rather than calling the API for every message.
Pagination
Lists use cursor pagination.
limitsets the page size: default 25, maximum 100.- The response's
meta.nextCursoris an opaque string. Pass it ascursorto get the next page. Keep the other parameters the same. - When
meta.nextCursorisnullyou've reached the end. - Cursors are not meant to be built or edited by hand, and may expire after a while; start again from the first page if one is rejected.
{
"data": [ { "rank": 1, "rating": 41250 } ],
"meta": { "nextCursor": "eyJvIjoxMDB9", "generatedAt": "2026-11-05T18:30:00Z" }
}
Batch lookups
Look up many players in one request instead of one request per player:
GET /v1/players?steamIds=76561198000000001,76561198000000002
GET /v1/players?ids=12,345,6789
GET /v1/players?username=PlayerName
- Up to 50 IDs per request, comma-separated.
- Unknown IDs are left out of
datarather than failing the whole request;meta.notFoundlists them. usernamematches the current username, case-insensitively. Usernames can change, so store the numericidor the Steam ID, not the name.
Errors
Errors use standard HTTP status codes and one JSON shape:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after 12 seconds.",
"requestId": "01JC4Q1S8M8Q7R2W3X4Y5Z6A7B"
}
}
| Status | code | Meaning |
|---|---|---|
| 400 | bad_request | A parameter is missing or invalid |
| 401 | unauthorized | No key, or the key is wrong or revoked |
| 403 | forbidden | The app is suspended or not active |
| 403 | origin_not_allowed | The browser origin isn't on the app's allowed origins |
| 403 | ip_not_allowed | The caller's IP isn't on the app's allowed IPs |
| 404 | not_found | No such season, player or match (or not public) |
| 429 | rate_limited | Over the per-minute or burst limit |
| 429 | quota_exceeded | Over the daily quota |
| 503 | overloaded | The service is shedding load; retry after Retry-After |
| 500 | internal | Something broke on our side |
Branch on code, not on message: messages may be reworded. Every response
has an X-Request-Id header; include it when you report a problem in your
support ticket.
Data notes
- Games. CS:GO and CS2 have separate ratings. Endpoints that depend on the
game take
?game=csgo(default) or?game=cs2. - Seasons are addressed by their number (
/v1/seasons/5) orcurrent. Only active and ended seasons are listed. Trophy images are absolute URLs. - Ratings and placement. A player's rating is
nullandplacedisfalseuntil they win their 6 placement matches in that season and game. - Ranks are positions in the season leaderboard. Banned players are left out, so past-season ranks can shift slightly when someone is banned later.
- CS2 has ratings, wins and matches, but no kill, damage or headshot
stats. ADR for CS:GO is only available for matches played since
19 June 2026; earlier seasons return
nullthere. - Matches. Only finished matches are available. Live or unfinished
matches return
404. - Deleted accounts return
404and don't appear on leaderboards. - Bans. Profiles include
banned:truewhile a matchmaking ban is active (short cooldowns don't count). Ban reasons are not part of the API. - Rates such as
winRateandheadshotRateare fractions from 0 to 1, not percentages. - Premium.
premiumTierisnone,basic,premiumormax. Expiry dates are not part of the API. - Deleted players in matches. A finished match keeps the stats of a player
who later deleted their account, with
playerset tonull. - IDs. Player
idis our stable numeric ID.steamIdis the Steam64 ID as a string (it doesn't fit safely in a JavaScript number). Usernames can change.
Best practices
- Proxy through your server. Keep the key server-side and let your own backend cache and serve your users.
- Cache first. Respect
Cache-Control, useETag/If-None-Match, and never poll faster than the data changes. - Back off. Honor
Retry-After, use exponential backoff with jitter and cap your retries. - Batch. Use
/v1/players?ids=or?steamIds=instead of many single lookups. - Identify yourself. Send a descriptive
User-Agentwith a way to reach you, e.g.PremierStatsBot/1.2 (+https://example.com; discord: yourname). - Don't scrape or enumerate. Don't walk through ID ranges or mirror whole datasets. Request what your users actually look at.
- Respect players. Show data in context, don't build tools to track, harass or expose individuals, and honor a player's request to be removed from your app.
- Attribute. Show "Data from csgopremier.com" with a link to https://csgopremier.com wherever the data appears.
- Expect additions. Ignore fields you don't know; new fields can appear at any time.
Examples
curl
curl -s "https://public-api.csgopremier.com/v1/players/steam/76561198000000001" \
-H "Authorization: Bearer $CSGOPREMIER_API_KEY" \
-H "User-Agent: MyBot/1.0 (+https://example.com)"
JavaScript (Node 18+, server-side) with an ETag cache and backoff:
const BASE = "https://public-api.csgopremier.com/v1";
const cache = new Map(); // url -> { etag, body }
async function premier(path, attempt = 0) {
const url = BASE + path;
const cached = cache.get(url);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.CSGOPREMIER_API_KEY}`,
"User-Agent": "MyBot/1.0 (+https://example.com)",
...(cached ? { "If-None-Match": cached.etag } : {}),
},
});
if (res.status === 304 && cached) return cached.body;
if ((res.status === 429 || res.status === 503) && attempt < 4) {
const retryAfter = Number(res.headers.get("Retry-After")) || 2 ** attempt;
const jitter = Math.random() * 1000;
await new Promise((r) => setTimeout(r, Math.min(retryAfter * 1000 + jitter, 60_000)));
return premier(path, attempt + 1);
}
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const etag = res.headers.get("ETag");
if (etag) cache.set(url, { etag, body });
return body;
}
const { data: player } = await premier("/players/steam/76561198000000001");
console.log(player.username, player.ratings.csgo?.rating);
Python with requests:
import os, random, time
import requests
BASE = "https://public-api.csgopremier.com/v1"
session = requests.Session()
session.headers.update({
"Authorization": f"Bearer {os.environ['CSGOPREMIER_API_KEY']}",
"User-Agent": "MyBot/1.0 (+https://example.com)",
})
def premier(path, params=None, attempts=4):
for attempt in range(attempts):
res = session.get(BASE + path, params=params, timeout=10)
if res.status_code in (429, 503):
wait = float(res.headers.get("Retry-After", 2 ** attempt))
time.sleep(min(wait + random.random(), 60))
continue
res.raise_for_status()
return res.json()
raise RuntimeError("gave up after retries")
# Walk a full leaderboard page by page.
cursor, rows = None, []
while True:
page = premier("/seasons/current/leaderboard",
{"game": "csgo", "limit": 100, **({"cursor": cursor} if cursor else {})})
rows += page["data"]
cursor = page["meta"]["nextCursor"]
if not cursor:
break
print(len(rows), "ranked players")
Versioning and deprecation
- The current version is v1, in the URL path. It is stable.
- Additive changes (new endpoints, new fields, new optional parameters, new error codes) can ship at any time without notice. Write clients that ignore unknown fields.
- Breaking changes (removing or renaming fields, changing types or
meanings) only happen in a new version such as
/v2. The old version keeps working for at least 90 days after the new one is announced, and deprecated responses carryDeprecationandSunsetheaders. - Changes are announced on this page and in the support tickets of active apps.
Terms of use
By requesting a key and using the API you agree to these terms, in addition to the site's Terms of Service and Privacy Policy.
- Attribution. Show "Data from csgopremier.com" with a link to https://csgopremier.com wherever the data is displayed.
- No reselling. Don't sell, license or redistribute the raw data or bulk copies of it. Building a product or service on top of it is fine.
- No impersonation. Don't present your app as made, endorsed or run by CSGO Premier, and don't use our logo in a way that suggests it.
- No harm to players. Don't use the data to harass, dox, stalk or discriminate against players, or combine it with other sources to identify people beyond what they show publicly.
- Respect the limits. Don't get around rate limits or quotas with extra accounts, apps or keys, and don't scrape the website instead of using the API.
- Keep keys secret. You're responsible for everything done with your key. Tell us at once if it leaks.
- Suspension. We can change limits, suspend or revoke a key or app at any time, especially for abuse, security issues or load problems, with or without notice.
- As is. The API and data are provided as is, without warranty or guaranteed uptime. We may change or end the API under the versioning policy above.
Questions about the terms go in your support ticket.
Endpoint reference
Generated from the OpenAPI 3.1 spec, which you can also load into Postman, Insomnia or a client generator. Open an endpoint for its parameters and an example response.
Meta
Health and this specification.
get/v1/statusService statusDetails
Health check. Needs no key, never touches the database, and is not rate limited per app.
Responses
200The service is up.
Example response (200)
{
"data": {
"status": "ok",
"version": "3f2a9c1",
"time": "2026-11-05T12:00:00Z"
}
}get/v1/openapi.jsonThis specificationDetails
The OpenAPI 3.1 document for this API. Needs no key.
Responses
200OpenAPI document.304Not modified: your cached copy (If-None-Match) is current.
Example response (200)
{}Seasons
Seasons, leaderboards and skill groups.
get/v1/seasonsList seasonsDetails
The active season and every ended season, newest first. Draft seasons are never listed.
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"id": 9,
"number": 5,
"name": "Season 5",
"status": "active",
"startedAt": "2026-10-01T00:00:00Z",
"endedAt": null,
"endsAt": "2027-01-01T00:00:00Z",
"ratingCap": 74999,
"trophyImageUrl": "https://csgopremier.com/static/seasons/9/1f0c.png"
}
]
}get/v1/seasons/{season}Get a seasonDetails
One season by number, or current.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
seasonrequired | path | string | Season number (e.g. `5`) or `current`. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": {
"id": 0,
"number": 0,
"name": "string",
"status": "active",
"startedAt": "2026-11-05T18:30:00Z",
"endedAt": "2026-11-05T18:30:00Z",
"endsAt": "2026-11-05T18:30:00Z",
"ratingCap": 0,
"trophyImageUrl": "https://csgopremier.com/"
}
}get/v1/seasons/{season}/leaderboardSeason leaderboardDetails
Ranked players of one season and title. Mirrors the site's boards: players currently banned, unplaced players and deleted accounts are left out. Equal ratings share a rank (1, 2, 2, 4). The board is a snapshot rebuilt about every minute for the current season (meta.generatedAt).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
seasonrequired | path | string | Season number (e.g. `5`) or `current`. |
game | query | string | Game title. Defaults to `csgo`.One of: "csgo", "cs2"Default: csgo |
limit | query | integer | Page size, 1–100.Default: 25 |
cursor | query | string | Opaque cursor from `meta.nextCursor`. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"rank": 0,
"player": {
"id": 0,
"username": "string",
"steamId": "string",
"avatarUrl": "https://csgopremier.com/",
"countryCode": "string"
},
"rating": 0,
"skillGroup": {
"id": 0,
"key": "string",
"name": "string",
"minRating": 0,
"maxRating": 0,
"imageUrl": "https://csgopremier.com/"
},
"wins": 0,
"matches": 0,
"winRate": 0
}
],
"meta": {
"season": 0,
"game": "csgo",
"total": 0,
"generatedAt": "2026-11-05T18:30:00Z",
"nextCursor": "string",
"limit": 0
}
}get/v1/ranksSkill groupsDetails
The 18 skill groups (Silver I to Global Elite) with their rating ranges and medal images. Both titles share one rating scale; the CS2 site shows the number with colour tiers instead of medals.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
game | query | string | Game title. Defaults to `csgo`.One of: "csgo", "cs2"Default: csgo |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"id": 0,
"key": "string",
"name": "string",
"minRating": 0,
"maxRating": 0,
"imageUrl": "https://csgopremier.com/"
}
]
}Players
Player profiles, season records and match history.
get/v1/playersLook up playersDetails
Batch lookup. Pass exactly one of ids (up to 50), steamIds (up to 50, any supported format) or username (current username, case-insensitive). Results keep the request order; inputs with no public player are listed in meta.notFound.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ids | query | string | Comma-separated player ids (max 50). |
steamIds | query | string | Comma-separated Steam IDs in any supported format (max 50). |
username | query | string | Current username, case-insensitive. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"id": 0,
"username": "string",
"steamId": "string",
"avatarUrl": "https://csgopremier.com/",
"countryCode": "string",
"profileUrl": "https://csgopremier.com/",
"premiumTier": "none",
"banned": false,
"currentSeason": 0,
"ratings": {
"csgo": {
"rating": 0,
"placed": false,
"placementWinsRemaining": 0,
"skillGroup": {
"id": null,
"key": null,
"name": null,
"minRating": null,
"maxRating": null,
"imageUrl": null
},
"rank": 0,
"wins": 0,
"matches": 0,
"winRate": 0
},
"cs2": {
"rating": 0,
"placed": false,
"placementWinsRemaining": 0,
"skillGroup": {
"id": null,
"key": null,
"name": null,
"minRating": null,
"maxRating": null,
"imageUrl": null
},
"rank": 0,
"wins": 0,
"matches": 0,
"winRate": 0
}
}
}
],
"meta": {
"notFound": [
"string"
]
}
}get/v1/players/steam/{steamId}Get a player by Steam IDDetails
Accepts SteamID64 (76561198…), STEAM_0:1:23, [U:1:47] or a bare account id. Vanity names are not resolved.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
steamIdrequired | path | string | SteamID64, STEAM_X:Y:Z, [U:1:N] or account id. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": {
"id": 4211,
"username": "s1mpleFan",
"steamId": "76561198000000001",
"avatarUrl": "https://csgopremier.com/static/avatars/4211/2b1c.jpg",
"countryCode": "NL",
"profileUrl": "https://csgopremier.com/s1mpleFan",
"premiumTier": "premium",
"banned": false,
"currentSeason": 5,
"ratings": {
"csgo": {
"rating": 18250,
"placed": true,
"placementWinsRemaining": 0,
"skillGroup": {
"id": 13,
"key": "mge",
"name": "Master Guardian Elite",
"minRating": 17500,
"maxRating": 19999,
"imageUrl": "https://csgopremier.com/static/classic_ranks/mge.svg"
},
"rank": 412,
"wins": 61,
"matches": 109,
"winRate": 0.5596
},
"cs2": {
"rating": null,
"placed": false,
"placementWinsRemaining": 4,
"skillGroup": null,
"rank": null,
"wins": 2,
"matches": 3,
"winRate": 0.6667
}
}
}
}get/v1/players/{id}Get a playerDetails
A player's public profile. Ids are stable; usernames can change.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | integer (int64) | Player id. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": {
"id": 4211,
"username": "s1mpleFan",
"steamId": "76561198000000001",
"avatarUrl": "https://csgopremier.com/static/avatars/4211/2b1c.jpg",
"countryCode": "NL",
"profileUrl": "https://csgopremier.com/s1mpleFan",
"premiumTier": "premium",
"banned": false,
"currentSeason": 5,
"ratings": {
"csgo": {
"rating": 18250,
"placed": true,
"placementWinsRemaining": 0,
"skillGroup": {
"id": 13,
"key": "mge",
"name": "Master Guardian Elite",
"minRating": 17500,
"maxRating": 19999,
"imageUrl": "https://csgopremier.com/static/classic_ranks/mge.svg"
},
"rank": 412,
"wins": 61,
"matches": 109,
"winRate": 0.5596
},
"cs2": {
"rating": null,
"placed": false,
"placementWinsRemaining": 4,
"skillGroup": null,
"rank": null,
"wins": 2,
"matches": 3,
"winRate": 0.6667
}
}
}
}get/v1/players/{id}/seasonsA player's seasonsDetails
The current season plus every ended season the player has a record in, newest first. K/D statistics exist for CS:GO only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | integer (int64) | Player id. |
game | query | string | Game title. Defaults to `csgo`.One of: "csgo", "cs2"Default: csgo |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"season": {
"number": 0,
"name": "string",
"status": "active"
},
"game": "csgo",
"rating": 0,
"placed": false,
"skillGroup": {
"id": 0,
"key": "string",
"name": "string",
"minRating": 0,
"maxRating": 0,
"imageUrl": "https://csgopremier.com/"
},
"rank": 0,
"wins": 0,
"matches": 0,
"winRate": 0,
"stats": {
"gamesTracked": 0,
"kills": 0,
"deaths": 0,
"assists": 0,
"headshots": 0,
"kdRatio": 0,
"avgKills": 0,
"adr": 0,
"headshotRate": 0
}
}
]
}get/v1/players/{id}/seasons/{season}A player's seasonDetails
One season record with the per-map win/loss record.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | integer (int64) | Player id. |
seasonrequired | path | string | Season number (e.g. `5`) or `current`. |
game | query | string | Game title. Defaults to `csgo`.One of: "csgo", "cs2"Default: csgo |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": {
"season": {
"number": 0,
"name": "string",
"status": "active"
},
"game": "csgo",
"rating": 0,
"placed": false,
"skillGroup": {
"id": 0,
"key": "string",
"name": "string",
"minRating": 0,
"maxRating": 0,
"imageUrl": "https://csgopremier.com/"
},
"rank": 0,
"wins": 0,
"matches": 0,
"winRate": 0,
"stats": {
"gamesTracked": 0,
"kills": 0,
"deaths": 0,
"assists": 0,
"headshots": 0,
"kdRatio": 0,
"avgKills": 0,
"adr": 0,
"headshotRate": 0
},
"maps": [
{
"map": {
"slug": "string",
"name": "string",
"imageUrl": "https://csgopremier.com/"
},
"wins": 0,
"losses": 0,
"winRate": 0
}
]
}
}get/v1/players/{id}/matchesA player's matchesDetails
Finished matches of one title, newest first. ratingChange is the published change the site shows, or null (placement, unrated mode, reverted or invalidated).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | integer (int64) | Player id. |
game | query | string | Game title. Defaults to `csgo`.One of: "csgo", "cs2"Default: csgo |
season | query | string | Only matches of this season (number or `current`). |
limit | query | integer | Page size, 1–100.Default: 25 |
cursor | query | string | Opaque cursor from `meta.nextCursor`. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"id": 0,
"game": "csgo",
"mode": "string",
"map": {
"slug": "string",
"name": "string",
"imageUrl": "https://csgopremier.com/"
},
"season": 0,
"playedAt": "2026-11-05T18:30:00Z",
"team": "A",
"score": {
"team": 0,
"opponent": 0
},
"result": "win",
"ratingChange": 0,
"ratingInvalidated": false
}
],
"meta": {
"nextCursor": "string",
"limit": 0
}
}Matches
Finished match scoreboards.
get/v1/matches/{id}Get a matchDetails
Scoreboard of a finished match. Live and unfinished matches return 404. Deleted accounts appear with player: null.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | integer (int64) | Match id. |
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).404No such public resource.429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": {
"id": 0,
"game": "csgo",
"mode": "string",
"map": {
"slug": "string",
"name": "string",
"imageUrl": "https://csgopremier.com/"
},
"region": "string",
"season": 0,
"startedAt": "2026-11-05T18:30:00Z",
"endedAt": "2026-11-05T18:30:00Z",
"score": {
"a": 0,
"b": 0
},
"winner": "A",
"ratingInvalidated": false,
"players": [
{
"player": {
"id": 0,
"username": "string",
"steamId": null,
"avatarUrl": "https://csgopremier.com/",
"countryCode": null
},
"team": "A",
"stats": {
"kills": 0,
"deaths": 0,
"assists": 0,
"damage": 0,
"headshots": 0
},
"ratingChange": 0
}
]
}
}Maps
The map catalogue.
get/v1/mapsList mapsDetails
Every map that can be queued in at least one mode, with its image and modes.
Responses
200OK304Not modified: your cached copy (If-None-Match) is current.400A parameter is invalid.401Missing, invalid, revoked or suspended key.403The request's Origin or IP address is not allowed for this app (`origin_not_allowed`, `ip_not_allowed`).429Rate limit (`rate_limited`) or daily quota (`quota_exceeded`) reached.503The API is busy; retry after `Retry-After` seconds with backoff.
Example response (200)
{
"data": [
{
"slug": "string",
"name": "string",
"game": "csgo",
"category": "string",
"imageUrl": "https://csgopremier.com/",
"modes": [
"string"
]
}
]
}