Loading documentation…
Loading documentation…
Collect a complete inventory in the background, then read it with Current.
Refresh asks SteamCall to collect a complete inventory in the background. It reserves credits or subscription units while collection runs and returns a refresh ID so you can check progress. Only a complete successful scan becomes a saved inventory that Current can read.
Open POST Refresh in API Reference
Credit amounts in this guide illustrate prepaid funding. A subscription-funded Refresh reserves fresh inventory units and settles by the same observed-asset rule; it does not also deduct prepaid credits. See Usage & credits.
Use a new Idempotency-Key for each new refresh. This identifies one request so a retry does not start duplicate work. Reuse the same key and inputs if you are unsure whether your first request was accepted. Reusing it with different inputs returns a conflict.
Set STEAMCALL_API_KEY to your Credential secret in your server environment. Replace the example Steam ID and idempotency key before running the request. All responses below use synthetic data.
curl --fail-with-body --max-time 15 \
--request POST \
'https://api.steamcall.com/v2/steam/users/76561198000000000/inventory/440/2/refresh' \
--header "X-API-Key: $STEAMCALL_API_KEY" \
--header "Idempotency-Key: inventory-76561198000000000-2026-08-23T1842Z" \
--header 'Content-Type: application/json' \
--data '{"language":"english","max_credits":125}'max_credits is the maximum charge you authorize, not the final charge. Refresh requires a 125-credit reservation; authorizing fewer credits rejects the request before work starts. The final charge is one credit per started 2,000 observed assets. A 1,500-item completed inventory costs 1 credit; 2,001 items cost 2; 100,000 cost 50; 250,000 cost 125. Unused reserved credits are released, and SteamCall retries do not increase the charge.
{
"success": true,
"data": {
"refresh_id": "5f2dd87e-92df-4f93-a944-c9cfc2b93470",
"scope": {
"steam_id": "76561198000000000",
"app_id": 440,
"context_id": 2
},
"state": "queued",
"requested_at": "2026-08-23T18:42:00Z",
"completed_at": null,
"outcome": null,
"revision_id": null,
"billing_state": "reserved",
"billing_disposition": null,
"billing": {
"state": "reserved",
"disposition": null,
"credits_reserved": 125,
"credits_charged": null,
"credits_released": null
}
},
"meta": {
"request_id": "req_01KREFRESH",
"product_code": "steam.inventory.refresh.v1",
"price_version": 1,
"credits_reserved": 125,
"billing_disposition": "reserved",
"rate_limit": {
"limit_per_minute": 120,
"remaining": 119,
"reset_seconds": 30
}
}
}The response is 202 Accepted, not a completed inventory. Store data.refresh_id and use the Location header as the status URL. Wait the number of seconds in Retry-After before polling. Both accepted and queued mean work is still pending; keep checking status rather than submitting a new refresh.
curl --fail-with-body --max-time 15 \
'https://api.steamcall.com/v2/steam/inventory-refreshes/5f2dd87e-92df-4f93-a944-c9cfc2b93470' \
--header "X-API-Key: $STEAMCALL_API_KEY"Open GET Refresh status in API Reference
Use an active Credential from the same Project as the original request to read its status.
A Credential from another Project cannot read it, even within the same customer account.
Replace the example refresh ID with the ID from your accepted response. Status reads charge zero credits but still
count toward the Service Account's request limit. Poll with bounded backoff: start from
Retry-After, honor
the updated value on every nonterminal response, stop at your workflow deadline, and resume later
using the same refresh ID. SteamCall omits Retry-After once collection and billing are terminal.
{
"success": true,
"data": {
"refresh_id": "5f2dd87e-92df-4f93-a944-c9cfc2b93470",
"scope": {
"steam_id": "76561198000000000",
"app_id": 440,
"context_id": 2
},
"state": "completed",
"requested_at": "2026-08-23T18:42:00Z",
"completed_at": "2026-08-23T18:42:06Z",
"outcome": "complete_changed",
"revision_id": "invrev_01KEXAMPLE",
"billing_state": "finalized",
"billing_disposition": "finalize_complete",
"billing": {
"state": "finalized",
"disposition": "finalize_complete",
"credits_reserved": 125,
"credits_charged": 2,
"credits_released": 123
}
},
"meta": {
"request_id": "req_01KSTATUS"
}
}Completed complete_changed and complete_unchanged scans are billed by observed size because both
perform complete collection. Confirmed private or not-found results settle the minimum diagnostic
charge. Upstream unavailable, incomplete, cancelled, and internal failures release the reservation.
Treat billing.state as part of completion. credits_reserved is the original maximum hold;
credits_charged is the terminal price; credits_released is the unused hold returned to the
available balance. While billing is reserved or pending, the terminal amounts remain null and
the free status operation may be polled again.
SteamCall can temporarily pause new refresh requests when it cannot safely accept more work. These rejected requests do not reserve credits. You can still check existing refreshes and read saved inventories with Current.
{
"success": false,
"error": {
"code": "product_unavailable",
"message": "This endpoint is temporarily unavailable",
"request_id": "req_01KOVERLOAD",
"detail": {
"admission_state": "closed",
"reason": "global_outstanding_closed"
}
}
}Honor Retry-After, keep the same idempotency key for the same request, and retry with bounded
jitter. A rejected admission creates no reservation. Do not fall back to an unbounded Live Page
traversal merely because Complete Refresh is temporarily closed.
After a successful completed outcome, call Current inventory. Do not use the refresh response as inventory data; it deliberately reports workflow and billing state only.
Continue with Build an inventory integration for complete Python and TypeScript workflows.
Where Events is enabled, use a signed webhook or authenticated Project stream to learn when a refresh reaches a terminal outcome. Correlate the notification's Refresh ID with the request you accepted, deduplicate by event ID, and inspect the outcome before reading Current. A terminal notification can describe a private or failed inventory; it does not contain the inventory or guarantee a successful refresh.
Keep bounded status polling as a fallback when Events is unavailable. After a disconnect or missed notification, follow Events recovery and reconcile refresh status before reading Current. Events is not generally available and does not provide Images preparation notifications.