Loading…

Migrating from the v1 API

The legacy API at rust.scmm.app is replaced by this one. This page maps what you call today onto what you should call now — all 69 v1 endpoints, including the ones with no successor.

Nothing here is a pure rename. The service was rewritten, so paths moved, ids changed type and one whole parameter disappeared. Read the four breaking changes first: they affect every request you make, and three of them fail silently.

Four things that change everywhere

1. Item ids changed type. v1 ids were 64-bit integers (the Steam assetDescriptionId). v2 ids are GUID strings. Every id you have stored is dead — a v1 id will not resolve.

There are two ways out, and the second is better. The v2 item DTO still carries assetDescriptionId, so you can sweep the catalogue once, build an assetDescriptionId → guid table and rewrite your keys. Or stop storing ids: every endpoint that takes an item id also accepts the item’s nameHash — the same value v1 returned as marketHashName — which is stable across both APIs and readable in a log. Note the rename: v2 has no marketHashName field, so a straight port of that property access yields undefined.

Both of these work
curl "https://api.scmm.app/api/item/f6f4f1a2-1c3a-4b6e-9d0f-0a1b2c3d4e5f"
curl "https://api.scmm.app/api/item/Tempered%20AK47"

2. Money is integer hundredths, always. v1 gave you a per-currency scale and expected value / 10^scale. v2 is value / 100 for every currency, with no exceptions.

This is the one that will bite. scale is still on the currency DTO, so your v1 code keeps compiling and keeps producing the right answer for every currency where scale happens to be 2 — which is most of them. Delete the exponent at the boundary rather than leaving it to be discovered by a user in a currency you did not test.

3. language is gone. Every v1 path accepted language and currency. v2 has no language parameter anywhere and no /api/language endpoint. Strip it. currency survives, with the same 3-letter codes, on the endpoints that return money — but PLN and RUB no longer exist, so a hard-coded one now falls back to USD instead of erroring.

4. Pagination changed shape. v1 took start/count and returned { items, start, count, total }. v2 takes page (1-based)/pageSize and returns { items, page, pageSize, total }.

Not uniform yet: GET /api/marketplace/deals still takes start/count. The reference is authoritative per endpoint.

Authentication

v1 was fully open and said so. v2 keeps that for reads: the catalogue, prices, stores, workshop and inventory endpoints still take no credential. What changed is that the handful of endpoints touching your own account/api/profile/me, /api/profile/data, inventory import — now need an x-api-key header or a session cookie. See Authentication.

Items

v1Now
/api/item/api/itemstart/count → page/pageSize. exactMatch dropped. sortBy/sortDirection → a single sort key (name_asc, price_desc, newest, …) — v1 sorted by DTO property name, so those values do not carry over and an unrecognised one silently returns the default order. If you wrote -name, price, -price, -subscriptions or -timeAccepted against an earlier version of the reference, those still work as aliases; the reference lists the canonical keys.
/api/item/{id}/api/item/{id}id is now a GUID or nameHash (v1: marketHashName), not the int64 id.
/api/item/collection/{name}/api/item/collection/{name}
/api/item/filters/api/item/types + /api/item/collections + /api/item/colorsSplit into three endpoints.
/api/item/types/api/item/types
/api/item/type/{type}/demand/api/item/type/{type}/demand
/api/item/definitionArchives/api/item/definitionArchives
/api/item/definitionArchive/{digest}/api/item/definitionArchive/{digest}
/api/item/definitionArchive/{oldDigest}/compareTo/{newDigest}/api/item/definitionArchive/{oldDigest}/compareTo/{newDigest}
/api/item/{id}/buyOrders/api/item/{id}/buyOrders
/api/item/{id}/sellOrders/api/item/{id}/sellOrders
/api/item/{id}/sales/market/api/item/{id}/sales/marketochl dropped — daily points only.
/api/item/{id}/sales/store/api/item/{id}/sales/store
/api/item/{id}/topHolders/api/item/{id}/topHolders
/api/item/market-cap/items/api/statistics/marketCap/items
/api/item/market-cap/summary/api/statistics/marketCap
/api/item/prices/api/item/pricesStill one response for the whole catalogue. One shape now, not two: markets= adds a per-market prices[] rather than switching the response type. Join on nameHash. The offer quoted is the cheapest, where v1 preferred Steam.

Marketplace, store and workshop

v1Now
/api/marketplace/items/api/marketplace/items
/api/store/api/store
/api/store/current/api/store/current
/api/store/{id}/api/store/{id}
/api/store/nextUpdateTime/api/store/nextUpdateTime
/api/store/{id}/stats/itemRevenue/api/statistics/store/{id}/itemRevenue
/api/store/{id}/stats/itemSales/api/statistics/store/{id}/itemSales
POST /api/store/{id}/linkItemgoneAdmin-only in v2.
POST /api/store/{id}/unlinkItemgoneAdmin-only in v2.
/api/workshop/api/workshopShape change: submissions are grouped by acceptance week, not a flat paginated list.

Profile and inventory

v1Now
/api/profile/api/profile/me
PUT /api/profilePATCH /api/profile/me + PATCH /api/profile/me/preferences
/api/profile/data/api/profile/data
DELETE /api/profile/dataDELETE /api/profile/data
/api/profile/{id}/summary/api/profile/{id}
/api/profile/{id}/inventory/items/api/inventory/{profileId}Now paginated — returns a page object, not an array.
/api/profile/{id}/inventory/total/api/inventory/{profileId}/value
/api/profile/{id}/inventory/value/api/inventory/{profileId}/valueMosaic generation dropped (generateInventoryMosaic and its mosaic* params).
/api/profile/{id}/inventory/collections/api/inventory/{profileId}/collections
/api/profile/{id}/inventory/investment/api/inventory/{profileId}/performance/items
/api/profile/{id}/inventory/movement/api/inventory/{profileId}/performance
/api/profile/{id}/inventory/timeline/api/inventory/{profileId}/history
/api/profile/{id}/inventory/ownedgoneReturned unique owned class ids. No successor.
POST /api/profile/{id}/inventory/syncPOST /api/inventory/import/{steamId}Now requires auth. force is owner/admin only.
PUT /api/profile/{profileId}/inventory/combineAllgoneSteam-mutating. Not ported.
PUT /api/profile/{profileId}/inventory/item/{itemId}goneBuy-price setter. Not ported.
PUT /api/profile/{profileId}/inventory/item/{itemId}/combinegoneSteam-mutating. Not ported.
PUT /api/profile/{profileId}/inventory/item/{itemId}/splitgoneSteam-mutating. Not ported.

Statistics

v1Now
/api/stats/market/totals/api/statistics/market
/api/stats/market/indexFund/api/statistics/indexFund
/api/stats/market/cheapestListings/api/marketplace/dealsDefault mode.
/api/stats/market/flips/api/marketplace/deals?mode=flips
/api/stats/market/cheapestCraftableContainerCosts/api/marketplace/crafting
/api/stats/market/cheapestCraftingResourceCosts/api/marketplace/crafting
/api/stats/store/topSellers/api/statistics/store/{id}/topSellersNow per store, not global.
/api/stats/profiles/inventories/highestValue/api/inventory/leaderboard
/api/stats/profiles/inventories/total/api/inventory/leaderboard/stats
/api/stats/items/mostExpensive/api/item?sort=price_descsort takes a fixed key, not a v1 property name. See the /api/item row.
/api/stats/items/mostSupply/api/statistics/supplyGrouped by category, not a ranked item list.
/api/stats/items/mostDemanded/api/statistics/supplySame — grouped, not ranked.
/api/stats/market/activitygone
/api/stats/items/allTimeHighgone
/api/stats/items/allTimeLowgone
/api/stats/items/largestCollectionsgone
/api/stats/items/mostSaturatedgone
/api/stats/items/typeDistributiongone
/api/stats/profiles/inventories/myRankgone
/api/stats/profiles/inventories/recentlyValuedgone
/api/stats/profiles/largestCreatorsgone
/api/stats/contributorsgone
/api/stats/donatorsgone

App, currency and language

v1Now
/api/app/api/app + /api/app/currentdetailed dropped.
/api/currency/api/currencydetailed dropped; rates moved to /api/currency/{id}/exchange-rates. PLN and RUB removed.
/api/languagegoneNo language negotiation in v2.

The bulk price feed is back — with different numbers

GET /api/item/prices returns the whole catalogue in one response, at the same path it had in v1. If you were sweeping GET /api/item page by page as a workaround, stop — that is ~62 requests against a 100/minute limit and this is one.

Three differences matter, and the third changes your numbers without changing your code.

  • One response shape, not two. v1 returned a different object depending on whether you passed markets. v2 always returns the same object; passing markets= adds a prices array to it and restricts which markets are considered.
  • Your stored ids still work here. This is the one endpoint where they do: v1’s id on this response was the Steam class id, not the assetDescriptionId used elsewhere, and v2 returns it as classId. nameHash is still the better key to move to.
  • The price is the cheapest one, not Steam’s. v1 sorted first-party sources ahead of every third-party market regardless of price, so it reported Steam’s number even when somewhere else was far cheaper. v2 reports the genuinely cheapest offer and names it in marketType.

Expect most prices to drop when you switch. Measured across our catalogue: of the items quoted by both Steam and a third-party market, a third party was cheaper on 96% of them, by a median of 37%. If you have alerting on price movement, expect it to fire on the day you migrate. If you specifically want Steam’s price, ask for it: ?markets=SteamCommunityMarket.

Compare on price + fee. v1 gave you a bare price. v2 also returns fee — our model of what buying on that market really costs — and it is often negative, because some markets sell below face value through bonus balance. Two other small changes in the same family: an item nothing sells is price: null where v1 said 0, and supply is null when the market reports no count.

Gaps, stated plainly

Four things v1 did that v2 does not. We would rather you read it here than find out in production.

  • Thirteen statistics endpoints have no successor — the allTimeHigh/allTimeLow/typeDistribution family, market activity, the profile leaderboards beyond value, and contributors/donators.
  • The Steam-mutating inventory routes are gone. Combine, split and combineAll required you to hand us your Steam Web API key. v2 does not accept one, by design.
  • OCHL candles and inventory mosaics are gone. Market sales return daily points; inventory value returns a number, not an image.
  • Workshop search changed shape, not just its path — submissions come back grouped by acceptance week rather than as a flat list.

Tell us which gap blocks you, in our Discord. That is what drives the order we close them in.

New in v2

EndpointWhat it does
/api/item/{id}/prices/historyOne item’s price history — a series per third-party market. See the per-market transpose below for one market’s whole catalogue.
/api/item/creator/{steamId}A Steam creator's full item catalogue.
/api/marketplace/{market}/prices/historyOne market's whole catalogue as a 30/60/90-day price aggregate, in a single request. Supports windows=, fields=, stats= and an incremental since= cursor.
/api/marketplace/{market}/sales-summaryA market's own completed-sale statistics (avgSalePrice, volume) — the sale side of the listing prices above.
/api/marketplace/marketsPer-market metadata: verified flags, bulk-buy support, CTA emphasis.
/api/marketplace/dealsRanked deals and Steam flips in one endpoint.
/api/statistics/indexesEvery Rust skin index, valued at the latest snapshot.
/api/statistics/indexes/historyDaily level series per index.
/api/statistics/marketCap/historyDaily market-cap series with a badge summary.
/api/store/rotationActive rotation timing for a countdown.
/api/statistics/store/{id}/subscribersCumulative workshop-subscriber timeline per store item.
/api/workshop/{id}Full detail for one workshop submission.
/api/inventory/{profileId}/performance/*Portfolio performance: history, events, collections, CSV.
/api/searchCross-entity search over items, creators and collections.
/api/game-eventsDated in-game events for annotating price charts.
/api/system/statusPer-market ingestion health and pipeline freshness.

Suggested migration order

  • Re-point the base URL to https://api.scmm.app and delete every language parameter. Both fail loudly, so do them first and let the errors guide you.
  • Fix money handling — divide by 100, delete scale. Do this before anything that reads a price, because it fails silently.
  • Switch your item keys to nameHash (v1’s marketHashName, renamed), or build the assetDescriptionId → guid remap.
  • Convert pagination to 1-based page/pageSize and read the new envelope.
  • Re-point the moved trees last — statistics (/api/stats/api/statistics) and inventory (/api/profile/{id}/inventory/api/inventory/{profileId}).