Search filters
Steam Market search is expressed two ways, over the same path:
| Form | Selection carried in | Returns |
|---|---|---|
GET /market/search | Query string | HTML page or SSR loader payload |
POST /market/search | JSON body | Search data or literal null |
The two accept the same selection, so a search assembled as a shareable URL can be replayed against the structured endpoint. The query string cannot express price bounds, numeric asset-property ranges, or paging, so anything beyond a simple search belongs on the POST form.
The body is a JSON array containing one request object:
[
{
"appid": 730,
"filters": { "Type": ["CSGO_Type_SniperRifle"] },
"accessoryFilters": {},
"propertyFilters": {},
"price": { "eCurrency": 1 },
"start": 0
}
]How filters combine
Values inside one array are ORed. Separate keys are ANDed, and the text query is ANDed with all of them. In the query string, repeat a parameter to OR its values:
?appid=730
&category_Type=CSGO_Type_SniperRifle&category_Type=CSGO_Type_Rifle
&category_Exterior=WearCategory0
selects (Sniper Rifle or Rifle) and Factory New. The body equivalent:
{ "filters": { "Type": ["CSGO_Type_SniperRifle", "CSGO_Type_Rifle"], "Exterior": ["WearCategory0"] } }Send filters and accessoryFilters as empty objects rather than omitting them.
Catalog tags
Query parameter category_{Category}; body key {Category} under filters. Values are tag
internal names.
Type
| Value | Label |
|---|---|
CSGO_Type_Pistol | Pistol |
CSGO_Type_SMG | SMG |
CSGO_Type_Rifle | Rifle |
CSGO_Type_SniperRifle | Sniper Rifle |
CSGO_Type_Shotgun | Shotgun |
CSGO_Type_Machinegun | Machinegun |
CSGO_Type_Knife | Knife |
Type_Hands | Gloves |
CSGO_Type_WeaponCase | Container |
CSGO_Tool_Sticker | Sticker |
CSGO_Type_Spray | Graffiti |
CSGO_Type_Collectible | Collectible |
Type_CustomPlayer | Agent |
Exterior
| Value | Label |
|---|---|
WearCategory0 | Factory New |
WearCategory1 | Minimal Wear |
WearCategory2 | Field-Tested |
WearCategory3 | Well-Worn |
WearCategory4 | Battle-Scarred |
Rarity
Shown as "Quality" in the Market UI.
| Value | Label |
|---|---|
Rarity_Common_Weapon | Consumer Grade |
Rarity_Uncommon_Weapon | Industrial Grade |
Rarity_Rare_Weapon | Mil-Spec Grade |
Rarity_Mythical_Weapon | Restricted |
Rarity_Legendary_Weapon | Classified |
Rarity_Ancient_Weapon | Covert |
Rarity_Ancient | Extraordinary |
Quality
Shown as "Category" in the Market UI.
| Value | Label |
|---|---|
normal | Normal |
strange | StatTrak™ |
tournament | Souvenir |
unusual | ★ |
unusual_strange | ★ StatTrak™ |
highlight | Highlight |
Weapon
weapon_ak47, weapon_aug, weapon_awp, weapon_bizon, weapon_famas, weapon_fiveseven,
weapon_g3sg1, weapon_galilar, weapon_hkp2000, weapon_knife_flip, weapon_m4a1,
weapon_m4a1_silencer, weapon_mag7, weapon_mp5sd, weapon_mp9, weapon_p250, weapon_p90,
weapon_revolver, weapon_sawedoff, weapon_scar20, weapon_sg556, weapon_ssg08, and the
remaining CS2 weapon identifiers.
Release-dependent categories
These grow with every game update. Read the current values from
GET /market/appfacets/{appid} rather than hard-coding them.
| Category | Value shape | Example |
|---|---|---|
ItemSet | set_* | set_anubis, set_dust_2, set_community_31 |
Tournament | Tournament{n} | Tournament25 (StarLadder Budapest 2025) |
TournamentTeam | Team{n} | Team12 (Natus Vincere) |
ProPlayer | lowercase handle | zywoo, s1mple, donk |
Applied accessories
Query parameter accessory_{Category}; body key accessory_{Category} under accessoryFilters.
Unlike catalog tags, accessories are matched by display name, exactly as returned by
GET /market/appaccessories/{appid}:
{
"accessoryFilters": {
"accessory_CSGO_Tool_Keychain": ["Charm | Stitch-Loaded"],
"accessory_CSGO_Tool_Sticker": [
"Sticker | BLAST.tv (Gold) | Paris 2023",
"Sticker | PGL (Gold) | Stockholm 2021"
]
}
}Two sentinels are accepted in place of a name:
| Sentinel | Matches |
|---|---|
$any$ | Items carrying any accessory of that kind |
$none$ | Items carrying none |
The categories are accessory_CSGO_Tool_Sticker and accessory_CSGO_Tool_Keychain.
Numeric properties
propertyFilters has no query-string equivalent. It is keyed by asset property ID as a string,
repeating the ID inside the value. Bounds are inclusive; Steam sends integer bounds as strings.
{ "propertyFilters": { "1": { "property_id": 1, "int_min": "385", "int_max": "678" } } }Continuous properties use float_min and float_max instead. Property IDs and their ranges are
application-specific.
Price
Body only, under price. Bounds are inclusive and in the minor units of eCurrency, so
unMin: 2063 is $20.63 when eCurrency is 1. Omit a bound to leave that end open.
{ "price": { "eCurrency": 1, "unMin": 2063, "unMax": 89135 } }Text
q in the query string, strQuery in the body. Add descriptions=1 or bSearchDescriptions: true to extend matching to item descriptions.
Sorting
sort and dir in the query string; sort and direction in the body.
sort | Column |
|---|---|
0, 4 | Popularity (default) |
1 | Name |
2 | Quantity |
3 | Price |
direction is 1 ascending or 2 descending. Popularity ignores direction. The Market UI offers
exactly these pairs: [0,2], [3,1], [3,2], [2,1], [2,2], [1,1], [1,2].
The legacy GET /market/search/render/ endpoint sorts differently, naming the column in
sort_column (popular, price, name, quantity) with sort_dir of asc or desc.
Paging
start is a zero-based offset in the body, bounded by total_count in the response. The Market UI
advances it in steps of 10 for grouped results and 30 for listing rows.
[{ "appid": 730, "filters": {}, "accessoryFilters": {}, "price": { "eCurrency": 1 }, "start": 30 }]Reading the vocabulary
Categories, tags, and accessory names are per-application and change with game updates.
GET /market/appfacets/{appid}returns every filter category, its tags, their localized labels, and match counts. Category keys map to filter names by dropping thecategory_prefix.GET /market/appaccessories/{appid}returns the sticker and charm display names. It is empty for applications with no applied-accessory system.

