CSFuse API
Version 1.0 · Base URL: https://csfuse.app/api/v1
Authentication
Most endpoints are public and require no authentication. Authenticated
endpoints (/me, /me/matches,
/auth/token) require a Bearer token.
Authorization: Bearer cf_<your_api_key>
API keys are issued by CSFuse admins from the admin panel. The raw token is shown only once at issuance — store it safely.
Rate limiting
- Public endpoints: 60 requests/minute per IP.
- Authenticated read endpoints: 120 requests/minute per API key.
- Write endpoints: 30 requests/minute per API key.
Responses include X-RateLimit-Limit,
X-RateLimit-Remaining, and
Retry-After headers.
Scopes
API keys carry a scope list. The server enforces them at request time — a key lacking the
required scope returns 403 insufficient_scope.
Read
read:matchesread:teamsread:statsread:live
Write
write:teamswrite:memberswrite:userswrite:matches(admin-tier only)
Identity
act:discord— enables X-Discord-User-ID
Idempotency
All POST write endpoints accept an
Idempotency-Key header. Send the same UUID within 24 hours
to safely retry a request: the first response is replayed and the operation is not executed
a second time. Reusing a key with a different path or body returns
422 idempotency_key_mismatch.
Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
Generate a fresh UUID v4 per distinct operation. Reusing a single key across two different operations will result in the second being rejected as a mismatch.
Bot integration (Discord)
To act on behalf of a Discord user, the bot sends its admin API key (with
act:discord scope) alongside an
X-Discord-User-ID header. The API resolves the header to a
CSFuse user via users.discord_id.
Authorization: Bearer cf_<bot_api_key>
X-Discord-User-ID: 123456789012345678
Idempotency-Key: <uuid>
If the Discord ID is not linked to any CSFuse user, the API returns
404 discord_user_not_found with a link_url:
{
"error": {
"code": "discord_user_not_found",
"message": "No CSFuse account is linked to this Discord user.",
"link_url": "https://csfuse.app/account"
}
}
Surface this URL in the bot so the user can complete account linking.
Typical flow
- User runs
/register 76561198067877321. Bot callsPOST /api/v1/users/link-steam. - Admin runs
/create-team "Alpha Squad" AS. Bot callsPOST /api/v1/teamswithX-Discord-User-ID= captain. - Admin runs
/add-player @user. Bot callsPOST /api/v1/teams/3/memberswith{"discord_id": "..."}. - If the target user hasn't linked a Steam account, the bot can still add them by
steam64— a placeholder account is created and adopted on first login.
Response format
Every response is JSON, wrapped in a consistent envelope.
Single resource
{
"data": { ... },
"meta": { }
}
Collection
{
"data": [ ... ],
"meta": {
"total": 142,
"per_page": 20,
"current_page": 1,
"last_page": 8
},
"links": { "first": "...", "next": "...", "last": "..." }
}
Error
{
"error": {
"code": "not_found",
"message": "Match not found."
}
}
Endpoints
/api/v1/api/v1/matches/api/v1/matches/{id}/api/v1/teams/api/v1/teams/{id}/api/v1/teams/{id}/stats/api/v1/maps/api/v1/maps/{id}/stats/api/v1/leaderboard/api/v1/live/api/v1/stats/api/v1/head-to-head/{a}/{b}/api/v1/me/api/v1/me/matches/api/v1/auth/token/api/v1/users/link-steam/api/v1/users/by-discord/{discord_id}/api/v1/teams/api/v1/teams/{id}/api/v1/teams/{id}/api/v1/teams/{id}/members/api/v1/teams/{id}/members/{steam64}/api/v1/teams/{id}/members/{steam64}/leader/api/v1/teams/{id}/members/{steam64}/leader/api/v1/matches/api/v1/matches/{id}/api/v1/matches/{id}Quick examples
List recent completed matches
curl "https://csfuse.app/api/v1/matches?status=completed&per_page=10"
Team statistics
curl "https://csfuse.app/api/v1/teams/1/stats"
Authenticated
curl -H "Authorization: Bearer cf_xxxxxxxx" "https://csfuse.app/api/v1/me"
Error codes
unauthorized— missing or invalid API key (401).insufficient_scope— key lacks the required scope (403).not_admin— endpoint requires an admin-tier key (403).not_authorized— caller is not a leader of this team (403).not_found— resource does not exist (404).discord_user_not_found— Discord ID is not linked to a CSFuse user (404).member_not_found— player is not on the team (404).team_not_found/format_not_found— referenced entity missing or inactive (404).steam_id_already_linked— Steam ID is already linked to a different account (409).already_a_member— user already on this team (409).validation_failed— invalid request parameters or body (422).team_name_taken/team_tag_taken— uniqueness conflict (422).team_at_capacity— team has hit the member cap (422).last_leader_cannot_be_removed/last_leader_cannot_be_demoted— promote another leader first (422).match_not_reschedulable/match_not_cancellable— match status forbids the action (422).idempotency_key_mismatch— same Idempotency-Key used with different path or body (422).too_many_requests— rate limit exceeded (429).
Security
The API never exposes dedicated server credentials — host, port, password, and RCON password are excluded from every response. Match server connection details are web-only and require an authenticated team leader account.