Loading documentation…
Loading documentation…
Keep an existing V1 integration working with its original inventory response and pagination.
Use this page if your application already calls a V1 inventory endpoint. These routes remain supported for compatibility but are deprecated for new integrations. New applications should use Live Page, or Refresh → Status → Current for complete saved inventories.
| Route | Reference | Failure body |
|---|---|---|
/api/v1/inventory/{steam_id}/{app_id}/{context_id} | Original V1 | Usually a detail string; validation errors use error |
/v1/steam/inventory/{steam_id}/{app_id}/{context_id} | V1 alias | An error object |
Both return the original unwrapped inventory body on success. Neither returns V2's data and meta envelope. Keep the route your client already handles; switching paths can change its error parsing.
Set STEAMCALL_API_KEY to your Service Account Credential secret in your local shell. Replace the example Steam ID with the public inventory you want to read.
curl --fail-with-body --max-time 15 \
'https://api.steamcall.com/api/v1/inventory/76561198000000000/440/2?language=english' \
--header "X-API-Key: $STEAMCALL_API_KEY"steam_id: the owner's 17-digit SteamID64.app_id: the Steam game ID; 440 is Team Fortress 2.context_id: the game's inventory context; TF2 player items normally use 2.language: description language, defaulting to english.start_assetid: omit on the first request. On subsequent requests, pass the previous response's last_assetid unchanged.The page size is fixed at up to 2,000 assets. There is no page_size or opaque cursor parameter on these routes.
A successful response uses top-level assets, descriptions, total_inventory_count, and success: 1. When another page exists, more_items is set and last_assetid supplies the continuation value. Keep asset IDs as strings; they can exceed JavaScript's safe integer range.
more_items is absent or zero, the traversal is complete.last_assetid as start_assetid with the same owner, game, context, and language.Inventories can change while you read them. A V1 traversal is not a pinned revision; use Current when you need pages from one saved revision.
This server-side example requires Python and the requests package. It requests at most 125 pages, checks a 120-second overall budget between requests, and gives each request at most 15 seconds of connect/read timeout. The HTTP timeout is not a strict wall-clock deadline for a streaming response. It does not automatically retry or publish partial results.
import os
import time
import requests
def read_legacy_inventory(steam_id, app_id=440, context_id=2):
url = f"https://api.steamcall.com/api/v1/inventory/{steam_id}/{app_id}/{context_id}"
headers = {"X-API-Key": os.environ["STEAMCALL_API_KEY"]}
params = {"language": "english"}
assets = {}
descriptions = {}
seen = set()
deadline = time.monotonic() + 120
for _ in range(125):
remaining = deadline - time.monotonic()
if remaining <= 0:
raise RuntimeError("Inventory read exceeded its deadline; results are incomplete")
response = requests.get(url, headers=headers, params=params, timeout=min(15, remaining))
response.raise_for_status()
body = response.json()
if body.get("success") != 1:
raise RuntimeError("Inventory page was not successful")
for asset in body.get("assets", []):
assets[asset["assetid"]] = asset
for description in body.get("descriptions", []):
key = (description["classid"], description["instanceid"])
descriptions[key] = description
if not body.get("more_items"):
return {"assets": list(assets.values()), "descriptions": list(descriptions.values())}
continuation = body.get("last_assetid")
if not isinstance(continuation, str) or not continuation.isdecimal() or continuation in seen:
raise RuntimeError("Missing or repeated continuation; results are incomplete")
seen.add(continuation)
params["start_assetid"] = continuation
raise RuntimeError("Inventory page limit reached; results are incomplete")Only replace your application's saved inventory after this function returns successfully. Preserve the previous data on failure; a private inventory is not an empty inventory.
Each requested page uses the Live Page price, not one price for the full inventory. A confirmed private-inventory response is also billable under the active price policy. Read X-Credits-Charged and X-Credits-Remaining; the original route also retains X-Api-Credits-Remaining for older clients. See Usage and credits.
| Status | What to do |
|---|---|
401 | Supply a valid X-API-Key. The original route uses API Key is missing or Invalid API Key. |
402 | Add enough credits before requesting another page. |
403 | Check permissions and inventory privacy. The original route returns Unauthorized for a missing scope or Inventory is private for privacy. |
404 | Check the inventory identifiers; do not treat this as a successful empty inventory. |
409 | Resolve the idempotency conflict or already-accepted request before retrying. |
422 | Correct the invalid path, query, or header value. Both V1 routes return a structured error object here. |
429 | Respect Retry-After. All active Credentials share their Service Account's limit; customer traffic-safety limits can also apply. |
500, 502, 503 | Preserve previous data and use bounded retries. Honor Retry-After when present. |
Keep the response's X-Request-ID for support. For exact schemas, open the original V1 reference or V1 alias reference.