Workshop & 1v1 Maps
Use Steam Workshop maps (1v1, AWP, aim, retake) in competitive matches and configure per-map gameplay overrides.
Workshop & 1v1 Maps
SweatHost competitive matches accept Steam Workshop maps in addition to stock CS2 maps. This is the canonical path for running 1v1 / AWP / aim / retake / arena matches against community-built layouts that aren't shipped with CS2.
There is one endpoint for all of this — the same POST /api/v1/matches you already use. You change the map and the match-level cvars; the server orchestration is identical.
How to specify a workshop map
In gameSettings.map (single map) or gameSettings.maps[] (BO3 / BO5 / map pool), pass the Steam Workshop PublishedFileId as a numeric string:
| Field value | Resolved as |
|---|---|
"de_dust2" | Stock CS2 map (changelevel de_dust2) |
"3070253400" | Workshop map (host_workshop_map "3070253400") |
"workshop/3070253400/aim_redline_fp" | ❌ Not supported — falls through to changelevel and fails |
The runtime detects "is this string all digits?" — if yes, it's treated as a workshop ID and downloaded from Steam; otherwise it's a stock map name. Mixing the two in a single match is fine:
"maps": ["de_mirage", "3070253400", "de_anubis"]Find a workshop ID
Open the workshop page (e.g. https://steamcommunity.com/sharedfiles/filedetails/?id=3070253400) — the id= value is what you submit. Subscribe to verify it's still listed; delisted items will not download.
First allocation downloads from Steam, subsequent ones hit cache
The first time a workshop ID is allocated in a region, the dedicated server downloads the map from Steam (typically 5–30 seconds for ~25–80 MB; up to ~30 seconds for 300 MB+ maps like Pool Day). Downloaded files cache to the region's shared EFS volume, so every subsequent allocation in that same region loads instantly. There is no extra setup needed — caching is automatic.
For a fully warm experience across multiple regions, you can pre-cache a whole workshop collection at fleet boot — see Pre-caching workshop collections below.
Endpoint
POST /api/v1/matches
Authorization: Bearer <api_key>
Content-Type: application/jsonThis is the same endpoint as for stock-map matches — see POST /matches for the full schema. The fields below are the ones most relevant to 1v1 / workshop play.
Request body
{
"region": "us-west-1",
"gameType": "cs2",
"externalMatchId": "awp-india-test-1",
"callbackUrl": "https://your.app/webhooks/match",
"gameSettings": {
"matchType": "competitive",
"map": "3070290869",
"maps": ["3070290869"],
"seriesFormat": "bo1",
"teams": {
"team1": { "name": "Ali", "players": ["76561198746925959"] },
"team2": { "name": "shyice", "players": ["76561198271164751"] }
},
"freezeTime": 3,
"maxRounds": 16,
"customCvars": "mp_roundtime 1.5\nmp_buy_anywhere 1\n"
}
}Field reference (gameSettings)
| Field | Type | Default | Notes |
|---|---|---|---|
matchType | string | required | Use "competitive" for all 1v1/AWP/aim maps. Workshop maps are not supported on deathmatch mode. |
map | string | required | The starting map. Workshop ID (numeric string) or stock name. |
maps | string[] | [map] | Map pool. For BO3/BO5, list 3 or 5 entries; mixed stock + workshop IDs allowed. |
seriesFormat | "bo1" | "bo3" | "bo5" | "bo1" | Series length. |
teams.team1.players / teams.team2.players | string[] | — | Steam ID 64s. Players outside the roster are kicked on connect. Submit only one player per team for 1v1. |
freezeTime | number (seconds) | 15 | Sets mp_freezetime. For 1v1, 2–5 is typical. |
maxRounds | number | — | Number of rounds in the match. For 1v1 first-to-N, set this to N (e.g. 8). |
customCvars | string | — | Newline-separated cvar overrides applied after the standard server.cfg. Use this for any cvar SweatHost doesn't expose as a top-level field. Lines beginning with // or # are ignored. |
Per-map configuration
Different workshop maps want different rules. Some are pure layouts that need server-side cvars to enforce gameplay (no buy, AWP loadout, short rounds); others embed their own loadout entities and just need to be loaded. Use customCvars to push per-match overrides without having to ship a new game mode.
Common 1v1 ruleset
Drop this into customCvars for AWP-only / aim 1v1 against bare-layout maps that don't enforce loadout themselves:
mp_freezetime 2
mp_round_restart_delay 1
mp_buytime 0
mp_buy_anywhere 0
mp_startmoney 0
mp_maxmoney 0
mp_afterroundmoney 0
mp_death_drop_gun 0
mp_solid_teammates 0
mp_friendlyfire 1
mp_t_default_primary weapon_awp
mp_ct_default_primary weapon_awp
mp_t_default_secondary weapon_deagle
mp_ct_default_secondary weapon_deagleFor a rifle/aim loadout, swap the two *_default_primary lines:
mp_t_default_primary weapon_ak47
mp_ct_default_primary weapon_m4a4Maps that embed entity logic
Some workshop maps (typically anything by crashz, sHNER, and similar makers) embed their own game_player_equip / point_servercommand entities that hand out weapons and reset money. Setting your own loadout cvars on top of those maps is harmless — the map's entities run last and win — but if you want to replicate what the map does naturally, leave customCvars blank and just submit the workshop ID.
Reference IDs for popular 1v1 maps
| Map | Workshop ID | Internal mapname | Type | Loadout source |
|---|---|---|---|---|
| awp_india | 3070290869 | awp_india | AWP layout | Server-side cvars |
| aim_redline_fp | 3070253400 | aim_redline_fp | Rifle/AWP layout | Server-side cvars |
| Bluelines 1v1/2v2 | 3070210382 | varies | Rifle + AWP | Server-side cvars |
| TIRGO 1v1 | 3070897497 | tirgo | Aim/Rifle | Server-side cvars |
| PIPSTEEZ 1v1 | 3357726265 | pipsteez | Aim (AK/M4/AWP) | Map-embedded |
| Crashz Dust 1v1 | 3087910523 | aim_crashz_dust_1on1 | Mixed loadout | Map-embedded |
| Pool Day Classic | 3070923343 | fy_pool_day | Pool fy_-style | Map-embedded |
Verify each ID is still listed on the workshop before pinning into your client — Steam delists items occasionally.
Examples
Single 1v1 — awp_india with AWP-only loadout
{
"region": "us-west-1",
"gameType": "cs2",
"externalMatchId": "awp-india-1v1",
"gameSettings": {
"matchType": "competitive",
"map": "3070290869",
"seriesFormat": "bo1",
"teams": {
"team1": { "name": "P1", "players": ["76561198000000001"] },
"team2": { "name": "P2", "players": ["76561198000000002"] }
},
"freezeTime": 2,
"maxRounds": 16,
"customCvars": "mp_buytime 0\nmp_buy_anywhere 0\nmp_startmoney 0\nmp_t_default_primary weapon_awp\nmp_ct_default_primary weapon_awp\nmp_t_default_secondary weapon_deagle\nmp_ct_default_secondary weapon_deagle"
}
}crashz Dust 1v1 — let the map handle loadout
{
"region": "us-west-1",
"gameType": "cs2",
"externalMatchId": "crashz-1v1",
"gameSettings": {
"matchType": "competitive",
"map": "3087910523",
"seriesFormat": "bo1",
"teams": {
"team1": { "name": "P1", "players": ["76561198000000001"] },
"team2": { "name": "P2", "players": ["76561198000000002"] }
},
"freezeTime": 3,
"maxRounds": 16
}
}Mixed BO3 — stock + workshop
{
"region": "us-west-1",
"gameType": "cs2",
"gameSettings": {
"matchType": "competitive",
"map": "de_mirage",
"maps": ["de_mirage", "3070253400", "de_anubis"],
"seriesFormat": "bo3",
"teams": { "team1": { "players": ["..."] }, "team2": { "players": ["..."] } }
}
}Pre-caching workshop collections
If you run a fixed set of workshop maps and want to skip the first-allocation download cost in every region, you can preload them at warm-pool boot. Build a Steam Workshop collection containing your IDs, then set +host_workshop_collection <collection_id> in the relevant fleet's CS2_LAUNCH_ARGS env. Every fresh pod downloads the entire collection on boot to its region's EFS; subsequent allocations of any map in the collection are instant.
Drawback: collection downloads run once per pod recycle, so frequent CS2 patches × large collections × many regions is a bandwidth cost. For curated 1v1 collections (~6 maps, ~700 MB total), this is negligible.
Connection flow
Once the match is created:
- The response contains the connect URL (
{ ip, port, connectUrl }). - The configured roster has 5 minutes from match creation to at least one player connecting, otherwise the match auto-cancels with
reason: "incomplete_roster"(see match webhooks). - Workshop maps require the CS2 client to also have the same workshop file. If a connecting client has a stale or missing copy, CS2 shows "client out of date" — the player must subscribe + redownload via Steam to fix it. This is independent of SweatHost.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
host_workshop_map ... did not load in API logs | Workshop ID is delisted, banned, or the connecting Steam ID does not have access. | Verify the page loads at steamcommunity.com/sharedfiles/filedetails/?id=<id>; pick a different ID if delisted. |
| Client gets "Client out of date" on connect | Player's local workshop copy of the map differs from the version Steam delivered to the server (or the player is on a CS2 beta branch). | Have the player unsubscribe + resubscribe to refresh the local cache. |
First allocation stuck in allocating for 30+ seconds | Workshop file is large (300+ MB) and downloading for the first time in this region. Subsequent allocations will be fast. | Wait for completion or pre-cache the collection (see above). |
| Loadout cvars don't take effect | The map embeds its own game_player_equip entities that override server cvars on respawn. | This is map-by-design. Either accept the map's loadout, or pick a layout-only map and apply your cvars there. |