SteamWebAPI to WOK API
Migrate from SteamWebAPI to WOK
Start with compatible endpoint paths. Validate prices, grouping, errors and quotas before switching your customers.
BASE_URL + API_KEY- BASE_URL = "https://www.steamwebapi.com"
+ BASE_URL = "https://woksteamapi.com"
- API_KEY = "your-steamwebapi-key"
+ API_KEY = "your-wok-key"
The legacy ?key= parameter works. Prefer a server-side Bearer header so the key stays out of URL logs.

Map the endpoints you use
WOK supports the inventory and profile paths below, not every SteamWebAPI feature or parameter. Native endpoints have different contracts.
For inventories larger than one Steam page, check pagination and batch coverage before changing your parser.
| Current call | WOK API | Notes |
|---|---|---|
/steam/api/inventory | GET /steam/api/inventory | Success is an item array. Grouped by default; validate missing prices, item fields and HTTP errors. |
/steam/api/profile | GET /steam/api/profile | One profile object. Check the documented fields rather than assuming full field parity. |
| Inventory totals and metadata | GET /v1/inventory | Native object with status, total, items and meta. Not an array replacement. |
| Multiple inventories | POST /v1/inventories | Native results[] envelope with per-pair success and errors. Adapt the payload and parser. |
| Price lookups | POST /v1/prices | Look up market hash names without scanning Steam; use the price API guide. |
Reference: WOK OpenAPI. FACEIT has its own documented WOK endpoints; it is not a claim of SteamWebAPI endpoint compatibility.
Migrate inventory pagination without losing items
Compare the returned scope before comparing item counts or valuations.
SteamWebAPI's current inventory documentation checked describes its batch result as the first Steam page per requested ID, at most 2,000 assets. An inventory fitting one page may already be complete. For larger inventories, its documented single-inventory continuation follows the last_assetid response header with start_assetid until that header is absent. A short item array alone is not a completion signal.
WOK follows the pages returned by its public Steam source before publishing a successful inventory. A failed continuation returns an error rather than a partial success. Existing safety limits and source deadlines still apply. This is public_only coverage, not proof of every owned item: Steam may omit recently received items. See the inventory scope and response contract.
When you need all item rows, use top=0 on WOK's native inventory GET or top: 0 in JSON or streaming batch payloads. The default top: 10 is a display projection, not the source inventory size. Grouped rows use count, so row count is not always asset quantity. If you opt into single-inventory output pagination with limit, it overrides native top; follow WOK's returned signed cursor with the same options. That cursor reads an existing cached snapshot; it is not Steam's start_assetid. Changed or expired snapshots return HTTP 409. Read the output pagination, currency and export contract before adapting continuation code.
Check a saved page sequence
This explicitly fictional example is a local acceptance fixture, not a provider response, account scan or price quote. Two successful saved pages contain 2,300 observed assets. If the second page fails, the first 2,000 assets are not a complete valuation. No request or API key is needed to inspect it.
{
"fictional": true,
"pages": [
{"saved_assets": 2000, "next_page": "saved-page-2"},
{"saved_assets": 300, "next_page": null}
],
"observed_assets": 2300
}
| Saved result | WOK native contract | Application decision |
|---|---|---|
| Successful returned pages | Read all requested rows and their count; retain public coverage and snapshot metadata. | Accept only the observed scope. A complete returned inventory can still have unpriced items. |
| Private inventory | A single native response can be HTTP 200 with status=private. A batch pair has ok=false and http_status=403. | Show unavailable/private data, never a confirmed zero-value inventory. |
| Observed empty inventory | Native status=empty is distinct from private or failed reads; the batch pair has ok=true. | Accept the explicit empty outcome for that observation, rather than infer it from any empty array. |
| Failed source or continuation | Native status=error or limited and failed batch pairs remain explicit. | Keep successful peers; do not publish an accumulated partial inventory as complete or replay the whole batch automatically. |
SteamWebAPI documents that private batch inventories may be an empty array or cached data. Validate those states against saved responses instead of treating every empty array as observed empty. WOK's single native route, compatibility route and native batches have different error envelopes; use the WOK OpenAPI contract and the existing offline response exercise. Streaming also needs its final verified complete record; see the stream completion and targeted retry rules.
Run a compatibility request
Set WOK_API_KEY in your server environment. Use a public SteamID64; the Python example requires the requests package.
inventorycurl --fail-with-body --max-time 35 -G "https://woksteamapi.com/steam/api/inventory" \
-H "Authorization: Bearer $WOK_API_KEY" \
--data-urlencode "steam_id=76561198090744629" \
--data-urlencode "game=cs2" \
--data-urlencode "currency=USD" \
--data-urlencode "price_source=auto" \
--data-urlencode "group=1"
requestsimport os
import requests
response = requests.get(
"https://woksteamapi.com/steam/api/inventory",
headers={"Authorization": f"Bearer {os.environ['WOK_API_KEY']}"},
params={
"steam_id": "76561198090744629",
"game": "cs2",
"currency": "USD",
"price_source": "auto",
"group": 1,
},
timeout=35,
)
response.raise_for_status() # Handle 403/410/429/5xx in your application.
items = response.json()
if not isinstance(items, list):
raise ValueError("Expected the WOK compatibility inventory array")
print("Sellable value (USD):", response.headers.get("X-Wok-Total"))
for item in items:
# Missing prices are unknown values, not proof that an item is worthless.
print(item["markethashname"], item["count"],
item["pricemedian"], item["pricesource"])
Choose a price source when needed
Pass price_source explicitly when comparing valuations. An omitted value uses the key or server default; auto explicitly chooses automatic selection.
autosteamsteam_buyskinportmarketbackpacktfbuffmix
?price_source=steam_buy&strict=1
auto uses an ordered preference, not the highest available price, and excludes BUFF163. mix selects the lowest eligible market price and can include a BUFF163 observation no older than 72 hours after an outlier check. Steam buy orders are excluded from both. Choose buff&strict=1 for BUFF-only values or steam_buy explicitly for a buy-order value.
strict=1 prevents fallback outside the selected mode; steam remains a family of Steam observations, not one feed. With a missing strict-source price, pricemedian can be null. Inspect pricesource, priceupdatedat and prices rather than assuming every item has that source.
Default single-inventory values are USD, not cents. On GET /steam/api/inventory and GET /v1/inventory, a supported currency, such as EUR, converts WOK valuation fields using a saved FX snapshot, without a per-request FX download. Non-USD FX must be no older than 24 hours; missing or stale FX returns HTTP 503 fx_unavailable with Retry-After: 60, and an unsupported saved-snapshot currency returns HTTP 400 unsupported_currency. Read X-Wok-Price-Currency and the FX response headers. Explicit provider-native currency records keep their original meaning; missing prices remain null. This does not add currency conversion to native batch requests. See the inventory output contract.
BUFF163 pricing covers supported CS2 catalog items; it does not provide BUFF account trading or order execution.
Check the contract before cutover
Replay a small set of saved responses in staging, then compare bounded live requests for the same SteamID, game and source.
Try twelve inventory cases without a key
Download inventory-contract-check.py and inventory-contract-fixtures.json into the same folder. Run the exercise locally with Python 3.10+; it makes no network requests and uses no API quota.
python3 inventory-contract-check.py
The data is explicitly fictional. The cases distinguish a successful compatibility array from a native object, a private HTTP 200 from an observed empty inventory, a partial known-price subtotal from a complete valuation, and successful batch pairs from failed peers. Grouped quantities use count, not market volume; only tradable and marketable units contribute to the sellable subtotal.
Edit a copy of the JSON to see inconsistent counts, totals or pair states fail. This is a teaching subset for full grouped USD responses, not a complete schema validator, a live quote or proof of SteamWebAPI parity. Keep null prices and unknown trade protection; compare snapshot age separately from item price timestamps. Then test your own parser against saved responses and the full WOK contract.
| Check | WOK behavior and acceptance check |
|---|---|
| Items and units | group=1 groups equivalent rows with count; group=0 exposes individual assetid strings. Check quantities, tradability and null prices. Use X-Wok-Total for the compatibility sellable total, not a sum of every row; its currency is X-Wok-Price-Currency, USD by default. |
| HTTP errors | Compatibility inventory: 403 private, 404 not found, 410 empty, 429 rate or capacity limit, 502 upstream failure. Handle authentication, quota and validation errors separately. Do not turn a failed scan into a zero-value inventory. |
| Native responses | A native inventory can return HTTP 200 with status=private, notfound, limited or error. For batches, inspect every results[].ok and results[].error; HTTP 200 does not mean all pairs succeeded. |
| Freshness | X-Wok-Cache-Age and X-Wok-Cache-TTL describe the inventory snapshot. Each item's priceupdatedat describes its selected catalog source. A cache hit can contain repriced items without a new Steam scan. |
| Repricing and retries | refresh_prices=1 reprices an active snapshot locally; a missing snapshot returns 404 INVENTORY_CACHE_MISS. Do not combine it with no_cache=1. Use bounded retries with backoff, and Retry-After when supplied. |
For native inventory batches, reserve one quota unit per player-game pair, with at most 80 pairs per call. A 20-player workload across eight games needs 160 units and at least two batches. GET /v1/key reports your effective remaining quotas without consuming a unit.
Route a small share of traffic only after these checks pass. Keep your previous configuration for rollback, and compare error rate, missing prices, inventory age and latency under the same workload. WOK is independent of SteamWebAPI; this guide does not promise complete feature parity.
Inventory response referenceCS2 inventory examplesInventory valuation rulesRate-limit handling
Plans
Prepaid access starts at 30 days and does not renew automatically. Pay by card, SBP, SberPay or USDT.
FREE DEVELOPER
Free
- units / 30 days
- 1 000
- units / day
- 100
- RPM
- 30
HISTORY
$6
- units / 30 days
- 750 000
- units / day
- 30,000
- RPM
- 600
PRICES STARTER
$6
- units / 30 days
- 250 000
- units / day
- 10,000
- RPM
- 300
PLAYERS STARTER
$8
- units / 30 days
- 60 000
- units / day
- 2,500
- RPM
- 300
VIEWER
$9
- units / 30 days
- 1 000
- units / day
- 100
- RPM
- 120
FLOAT
$9
- units / 30 days
- 100 000
- units / day
- 5,000
- RPM
- 300
PRICES
$9
- units / 30 days
- 600 000
- units / day
- 20,000
- RPM
- 600
INVENTORY STARTER
$12
- units / 30 days
- 150 000
- units / day
- 6,000
- RPM
- 400
HISTORY PRO
$12
- units / 30 days
- 3 000 000
- units / day
- 120,000
- RPM
- 1200
START
$15
- units / 30 days
- 300 000
- units / day
- 10,000
- RPM
- 250
ASSETS
$15
- units / 30 days
- 300 000
- units / day
- 15,000
- RPM
- 300
PLAYERS
$15
- units / 30 days
- 200 000
- units / day
- 7,000
- RPM
- 600
PRICES PRO
$19
- units / 30 days
- 2 000 000
- units / day
- 70,000
- RPM
- 1200
VIEWER PRO
$19
- units / 30 days
- 5 000
- units / day
- 500
- RPM
- 300
FLOAT PRO
$19
- units / 30 days
- 1 000 000
- units / day
- 50,000
- RPM
- 1200
INVENTORY
$25
- units / 30 days
- 450 000
- units / day
- 15,000
- RPM
- 800
HISTORY SCALE
$25
- units / 30 days
- 12 000 000
- units / day
- 450,000
- RPM
- 1500
ASSETS PRO
$29
- units / 30 days
- 1 000 000
- units / day
- 50,000
- RPM
- 1200
PLAYERS PRO
$29
- units / 30 days
- 500 000
- units / day
- 18,000
- RPM
- 1200
PRO
$35
- units / 30 days
- 700 000
- units / day
- 24,000
- RPM
- 500
PRICES SCALE
$39
- units / 30 days
- 6 000 000
- units / day
- 210,000
- RPM
- 1500
VIEWER SCALE
$39
- units / 30 days
- 12 500
- units / day
- 1,250
- RPM
- 600
FLOAT SCALE
$39
- units / 30 days
- 3 000 000
- units / day
- 120,000
- RPM
- 1500
INVENTORY PRO
$49
- units / 30 days
- 900 000
- units / day
- 32,000
- RPM
- 1500
ASSETS SCALE
$49
- units / 30 days
- 5 000 000
- units / day
- 200,000
- RPM
- 1500
HISTORY BUSINESS
$49
- units / 30 days
- 25 000 000
- units / day
- 900,000
- RPM
- 1500
PLAYERS SCALE
$59
- units / 30 days
- 1 100 000
- units / day
- 40,000
- RPM
- 1500
PRICES BUSINESS
$59
- units / 30 days
- 12 000 000
- units / day
- 420,000
- RPM
- 1500
MAX
$65
- units / 30 days
- 2 000 000
- units / day
- 80,000
- RPM
- 1000
FLOAT BUSINESS
$69
- units / 30 days
- 6 000 000
- units / day
- 220,000
- RPM
- 1500
PLAYERS BUSINESS
$89
- units / 30 days
- 1 750 000
- units / day
- 65,000
- RPM
- 1500
HISTORY ENTERPRISE
$89
- units / 30 days
- 50 000 000
- units / day
- 1,800,000
- RPM
- 1500
ASSETS BUSINESS
$89
- units / 30 days
- 10 000 000
- units / day
- 350,000
- RPM
- 1500
INVENTORY SCALE
$99
- units / 30 days
- 2 000 000
- units / day
- 70,000
- RPM
- 2000
PRICES ENTERPRISE
$99
- units / 30 days
- 25 000 000
- units / day
- 900,000
- RPM
- 1500
FLOAT ENTERPRISE
$119
- units / 30 days
- 12 000 000
- units / day
- 450,000
- RPM
- 1500
ULTRA
$139
- units / 30 days
- 7 000 000
- units / day
- 240,000
- RPM
- 1500
INVENTORY BUSINESS
$149
- units / 30 days
- 3 000 000
- units / day
- 110,000
- RPM
- 2500
ASSETS ENTERPRISE
$149
- units / 30 days
- 20 000 000
- units / day
- 700,000
- RPM
- 1500
PRICES ENTERPRISE PLUS
$179
- units / 30 days
- 50 000 000
- units / day
- 1,800,000
- RPM
- 1500
TITAN
$199
- units / 30 days
- 9 000 000
- units / day
- 350,000
- RPM
- 2500
PLAYERS ENTERPRISE
$199
- units / 30 days
- 4 000 000
- units / day
- 150,000
- RPM
- 1500
INVENTORY ENTERPRISE
$299
- units / 30 days
- 6 000 000
- units / day
- 220,000
- RPM
- 3000
PLAYERS ENTERPRISE PLUS
$389
- units / 30 days
- 8 000 000
- units / day
- 300,000
- RPM
- 1500
BUSINESS
$569
- units / 30 days
- 12 000 000
- units / day
- 450,000
- RPM
- 3000
INVENTORY ENTERPRISE PLUS
$569
- units / 30 days
- 12 000 000
- units / day
- 450,000
- RPM
- 3500
ENTERPRISE
$949
- units / 30 days
- 20 000 000
- units / day
- 750,000
- RPM
- 3500
ENTERPRISE PLUS
$1399
- units / 30 days
- 30 000 000
- units / day
- 1,100,000
- RPM
- 3500
Docs, OpenAPI and SDKsFull pricing detailsSteamWebAPI alternative