{"openapi":"3.1.0","info":{"title":"AssetPay Public API","version":"0.8.3","description":"Public trading API - skin deposits, withdrawals, pricing, client endpoints, and identity verification."},"servers":[{"url":"/"}],"tags":[{"name":"Client Authentication","description":"Client token issuance for trading operations"},{"name":"Trading","description":"Core trading operations (trade URL check, pricing)"},{"name":"Client","description":"Client-facing endpoints (inventory, trade history, market)"},{"name":"Deposits","description":"Skin deposit operations"},{"name":"Withdrawals","description":"Skin withdrawal operations"},{"name":"Crypto","description":"End-user USDT/USDC deposit addresses, deposits and cashouts on ETH, BSC and SOL"},{"name":"Verification","description":"Client identity verification via Signicat PictureID (document + selfie)"},{"name":"Wallet","description":"Merchant wallet balance"},{"name":"Ledger","description":"Wallet funding history"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Merchant or admin JWT access token"},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"api-key","description":"Merchant API key (format: ap_...)"},"ClientToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Client JWT token issued via authenticate-client"}},"schemas":{},"parameters":{}},"paths":{"/auth/authenticate-client":{"post":{"summary":"Authenticate a trading client","description":"Creates a client JWT token for a Steam user. Requires a merchant API key with CORE_ACCESS scope. The returned token is used by the client for inventory, deposit, and withdrawal endpoints.","tags":["Client Authentication"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"clientSteamId":{"type":"string","pattern":"^76561\\d{12}$"},"clientTradeUrl":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"},"clientData":{"type":"object","properties":{"totalWager":{"type":"number","minimum":0},"registrationDate":{"type":["string","null"],"format":"date-time"},"kycHash":{"type":"string"},"kycLevel":{"type":"integer","minimum":0},"fiatDeposits":{"type":"boolean"},"cryptoDeposits":{"type":"boolean"}}},"clientId":{"type":"string","maxLength":128}},"required":["clientSteamId","clientTradeUrl"],"additionalProperties":false}}}},"responses":{"200":{"description":"Client token issued","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/check-tradeurl":{"post":{"summary":"Check trade URL validity","description":"Validates a Steam trade URL and checks the user's trade eligibility (bans, escrow, privacy settings). Requires API key with CORE_ACCESS scope. Results are cached for 1 hour unless forceRefresh is true.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tradeurl":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"},"forceRefresh":{"type":"boolean","default":false}},"required":["tradeurl"],"additionalProperties":false}}}},"responses":{"200":{"description":"Trade URL check result","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"state":{"type":"integer","minimum":1,"maximum":10,"description":"1=Normal, 2=CS2Banned, 3=RustBanned, 4=Banned, 5=InventoryPrivate, 6=TradeUrlInvalid, 7=UserNotFound, 8=UnknownError, 9=UserNotTradeable, 10=SteamUnavailable"},"steamid":{"type":"string","description":"Steam ID of the user"},"message":{"type":"string","description":"Human-readable status message"},"canTrade":{"type":"boolean","description":"Whether the user can trade"},"reason":{"type":"object","properties":{"escrowDays":{"type":"integer"},"probation":{"type":"boolean"}},"required":["escrowDays","probation"],"description":"Trade restriction details"},"bans":{"type":"object","properties":{"vacBanned":{"type":"boolean"},"gameBans":{"type":"integer"},"economyBan":{"type":"string","description":"Steam economy ban state: none, probation or banned"}},"required":["vacBanned","gameBans","economyBan"],"description":"Steam ban record. A VAC ban blocks CS2 deposits (state 2, USER_NOT_TRADEABLE on deposit); game bans and Rust are unaffected"}},"required":["state","message"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/prices":{"get":{"summary":"Get item prices and offers","description":"Returns the current price book for a given game. Each item carries a `deposit` price (what AssetPay pays for the item) and a `withdraw` price (fee-inclusive buy price you can pass straight back to /secure/buy). For CS2, `withdraw` is split into `standard` and `instant` delivery and each entry includes the Skinshark catalog `itemId`; for Rust, `withdraw` is a single value. Doppler items are returned as a single entry with a `phases[]` breakdown, each phase carrying a deposit price and its own `withdraw.standard`/`withdraw.instant` (a phase often has a standard floor and no instant one, in which case `withdraw.instant` is null); the top-level `deposit`/`withdraw` carry the floor as a default. Withdraw prices already include your merchant fee. Requires API key with CORE_ACCESS scope.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","exclusiveMinimum":0,"default":730},"required":false,"name":"game","in":"query"}],"responses":{"200":{"description":"Per-item deposit and withdraw prices","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"itemId":{"type":["string","null"],"description":"Skinshark catalog item id, null when no withdraw floor"},"marketHashName":{"type":"string"},"accepted":{"type":"boolean","description":"Whether the item is accepted for deposit (deposit price > 0)"},"deposit":{"type":"number","description":"Deposit offer price in USD (what we pay for the item)"},"withdraw":{"type":"object","properties":{"standard":{"type":["number","null"]},"instant":{"type":["number","null"]}},"required":["standard","instant"],"description":"Fee-inclusive buy price per delivery mode; null when unavailable"},"phases":{"type":"array","items":{"type":"object","properties":{"phase":{"type":"string","enum":["Phase 1","Phase 2","Phase 3","Phase 4","Ruby","Sapphire","Black Pearl","Emerald"],"description":"Doppler phase label"},"accepted":{"type":"boolean","description":"Whether this phase is accepted for deposit (deposit price > 0)"},"deposit":{"type":"number","description":"Deposit offer price in USD for this phase (what we pay)"},"withdraw":{"type":"object","properties":{"standard":{"type":["number","null"]},"instant":{"type":["number","null"]}},"required":["standard","instant"],"description":"Fee-inclusive buy price in USD for this phase, per delivery mode; either is null when unavailable. A phase often has a standard floor and no instant one."}},"required":["phase","accepted","deposit","withdraw"]},"description":"Present for Doppler items: per-phase deposit + standard withdraw prices. The top-level deposit/withdraw carry the floor (cheapest phase / grouped floor) as a default."}},"required":["itemId","marketHashName","accepted","deposit","withdraw"]},{"type":"object","properties":{"marketHashName":{"type":"string"},"accepted":{"type":"boolean","description":"Whether the item is accepted for deposit (deposit price > 0)"},"deposit":{"type":"number","description":"Deposit offer price in USD (what we pay for the item)"},"withdraw":{"type":["number","null"],"description":"Fee-inclusive buy price in USD; null when unavailable"}},"required":["marketHashName","accepted","deposit","withdraw"]}]}}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/inventory":{"get":{"summary":"Get Steam inventory (merchant self-trade)","description":"Fetches a Steam account's inventory. The merchant passes a tradeUrl per request and AssetPay derives the steamId from it - no client authentication step is needed. Use this to discover items the merchant can sell to AssetPay via /secure/sell.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"default":false},"required":false,"name":"refresh","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"default":false,"description":"Return only items accepted for deposit (offer.accepted = true)"},"required":false,"description":"Return only items accepted for deposit (offer.accepted = true)","name":"acceptedOnly","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":730},"required":false,"name":"game","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"sort","in":"query"},{"schema":{"type":["number","null"]},"required":false,"name":"minPrice","in":"query"},{"schema":{"type":["number","null"]},"required":false,"name":"maxPrice","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":["integer","null"],"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"},"required":true,"name":"tradeUrl","in":"query"}],"responses":{"200":{"description":"Inventory items + collateral","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"inventory":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"count":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"},"collateral":{"type":"number"}},"required":["inventory","count","updatedAt","collateral"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"424":{"description":"Failed Dependency - Steam could not serve the request (inventory fetch failed, temporarily unavailable, or rate-limited upstream). The caller is not at fault; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/sell":{"post":{"summary":"Sell skins to AssetPay (merchant self-trade)","description":"Initiates a deposit-style trade where the merchant sends their own Steam items to AssetPay in exchange for USD wallet credit. Pricing must match the latest /secure/prices snapshot. Webhooks fire on state changes.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256},"price":{"type":"number","exclusiveMinimum":0},"amount":{"type":"integer","minimum":1,"maximum":10000,"default":1}},"required":["itemId","price"]},"minItems":1,"maxItems":250},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128},"isInstant":{"type":"boolean","default":false},"tradeUrl":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"}},"required":["items","tradeUrl"],"additionalProperties":false}}}},"responses":{"200":{"description":"Trade record","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"424":{"description":"Failed Dependency - Steam could not serve the request (inventory fetch failed, temporarily unavailable, or rate-limited upstream). The caller is not at fault; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/buy":{"post":{"summary":"Buy skins from the marketplace (merchant self-trade)","description":"Initiates a withdraw-style trade where AssetPay buys the requested listings from the upstream marketplace and delivers them to the supplied tradeUrl. The merchant wallet is debited. Optional `autoCancel` (minutes, 30-720, default 30; 720 disables) cancels still-undelivered items automatically after the period, with refunds settling via the trade webhook. CS2 only.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256},"price":{"type":"number","exclusiveMinimum":0,"maximum":100000,"description":"Price you quoted the end user. A lower current price is accepted and charged instead; a higher one is rejected unless it fits maxPrice or slippageBps."},"maxPrice":{"type":"number","exclusiveMinimum":0,"maximum":100000,"description":"Highest price you will pay for this item. Overrides slippageBps. Omit to reject any rise above price."},"externalId":{"type":"string","minLength":1,"maxLength":128,"description":"Your own reference for this item. Cancel accepts it in place of the item id."}},"required":["itemId","price"]},"minItems":1,"maxItems":50},"slippageBps":{"type":"integer","minimum":0,"maximum":2000,"description":"Upward tolerance in basis points applied to every item lacking maxPrice (100 = 1%). Defaults to 0."},"autoCancel":{"type":"integer","minimum":30,"maximum":720,"description":"Minutes after creation to automatically cancel still-undelivered items (30-720). Defaults to 30; 720 disables auto-cancel. CS2 only."},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128},"tradeUrl":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"}},"required":["items","tradeUrl"],"additionalProperties":false}}}},"responses":{"200":{"description":"Trade record","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/buy/quick":{"post":{"summary":"Quick-buy skins from the marketplace (merchant self-trade)","description":"Buys the N cheapest listings of a single item at or below a per-unit ceiling. Available for CS2 and Rust. Identify the item with either `itemId` or its exact `marketHashName` (itemId wins when both are sent); the per-unit `maxPrice` (fee-inclusive, gross) and `itemId` come from /secure/prices. `amount` is 1-200 and `delivery` is standard or instant. Optionally pin a Doppler `phase` (e.g. 'Ruby') to buy only that phase, priced against the phase floor for the requested delivery mode; phase and instant delivery are CS2-only. The trade starts empty and locks the worst-case total; the filled listings (possibly fewer than requested) and the refund of any unfilled / below-ceiling remainder settle asynchronously via the trade webhook. Optional `autoCancel` (minutes, 30-720, default 30; 720 disables) cancels still-undelivered items automatically after the period, with refunds settling via the trade webhook. CS2 only.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256,"description":"Item id from /secure/prices (Skinshark catalog id for CS2, listing id for Rust). Provide this OR marketHashName; when both are sent, itemId wins."},"marketHashName":{"type":"string","minLength":1,"maxLength":256,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied."},"maxPrice":{"type":"number","exclusiveMinimum":0,"maximum":100000},"amount":{"type":"integer","minimum":1,"maximum":200},"delivery":{"type":"string","enum":["standard","instant"],"default":"standard"},"phase":{"type":"string","enum":["Phase 1","Phase 2","Phase 3","Phase 4","Ruby","Sapphire","Black Pearl","Emerald"],"description":"Doppler phase to buy (e.g. 'Ruby'). Priced against the phase floor for the requested delivery mode."},"autoCancel":{"type":"integer","minimum":30,"maximum":720,"description":"Minutes after creation to automatically cancel still-undelivered items (30-720). Defaults to 30; 720 disables auto-cancel. CS2 only."},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128},"externalIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"description":"Your own reference per requested unit, one per item, applied in order. Must hold exactly `amount` entries. Cancel accepts them in place of the item id."},"tradeUrl":{"type":"string","pattern":"^https:\\/\\/steamcommunity\\.com\\/tradeoffer\\/new\\/\\?partner=\\d{1,10}&token=[A-Za-z0-9_-]{8}$"}},"required":["maxPrice","amount","tradeUrl"],"additionalProperties":false}}}},"responses":{"200":{"description":"Quick-buy trade initiated (items settle via webhook)","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/buy/{tradeId}/items/{itemId}/cancel":{"post":{"summary":"Cancel an undelivered buy item (merchant self-trade)","description":"Requests cancellation of a single undelivered item from a merchant self-trade buy. Skinshark (CS2) items only - Rust and internal-sourced items have no provider cancel and return TRADE_CANCEL_UNSUPPORTED. An item must be at least 30 minutes old and not yet terminal. On success the refund flows back via the trade webhook; the response only confirms the cancellation was accepted.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Internal trade id or the externalId supplied at creation."},"required":true,"description":"Internal trade id or the externalId supplied at creation.","name":"tradeId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":128,"description":"The item's `id`, or the `externalId` you supplied for it at buy time."},"required":true,"description":"The item's `id`, or the `externalId` you supplied for it at buy time.","name":"itemId","in":"path"}],"responses":{"200":{"description":"Cancellation accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"tradeId":{"type":"string","format":"uuid"},"itemId":{"type":"string","format":"uuid"},"externalId":{"type":"string"},"status":{"type":"string","enum":["cancelled"]}},"required":["tradeId","itemId","status"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/buy/{tradeId}/cancel":{"post":{"summary":"Cancel every undelivered item in a buy (merchant self-trade)","description":"Requests cancellation of every still-cancellable item in the trade. Skinshark (CS2) items only - Rust and internal-sourced items have no provider cancel and return TRADE_CANCEL_UNSUPPORTED. An item must be at least 30 minutes old and not yet terminal. On success the refund flows back via the trade webhook; the response only confirms the cancellation was accepted. Best effort: a partial result is still a 200, with a per-item status and reason, so check the body rather than the status code.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Internal trade id or the externalId supplied at creation."},"required":true,"description":"Internal trade id or the externalId supplied at creation.","name":"tradeId","in":"path"}],"responses":{"200":{"description":"Per-item cancellation outcomes","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"tradeId":{"type":"string","format":"uuid"},"requested":{"type":"integer","description":"Items the provider considered cancellable"},"cancelled":{"type":"integer"},"failed":{"type":"integer"},"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string"},"externalId":{"type":"string"},"status":{"type":"string","enum":["cancelled","failed"]},"reason":{"type":"string","description":"Stable error key when the cancel was refused, e.g. TRADE_CANCEL_TOO_SOON or TRADE_NOT_CANCELLABLE."}},"required":["itemId","status"]}}},"required":["tradeId","requested","cancelled","failed","items"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/market":{"get":{"summary":"Browse marketplace items (merchant self-trade)","description":"Search and paginate the merchant-facing marketplace. Same listings the merchant's clients see via /client/market.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","exclusiveMinimum":0,"default":730},"required":false,"name":"game","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","enum":["relevance","priceAsc","priceDesc","nameAsc","nameDesc"]},"required":false,"name":"sort","in":"query"},{"schema":{"type":["number","null"],"minimum":0},"required":false,"name":"minPrice","in":"query"},{"schema":{"type":["number","null"],"minimum":0},"required":false,"name":"maxPrice","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","default":50},"required":false,"name":"perPage","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}],"default":false,"description":"Sandbox flag. When true, every returned item is stamped with instant delivery, a placeholder preview token, and a synthetic holding bot so integrators can see the full item shape on cheap listings."},"required":false,"description":"Sandbox flag. When true, every returned item is stamped with instant delivery, a placeholder preview token, and a synthetic holding bot so integrators can see the full item shape on cheap listings.","name":"development","in":"query"},{"schema":{"type":"string","enum":["internal","external","Xk9W"]},"required":false,"name":"source","in":"query"}],"responses":{"200":{"description":"Marketplace search results","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"count":{"type":"integer"}},"required":["items","count"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/market/item":{"get":{"summary":"Get marketplace listings for one item (merchant self-trade)","description":"Returns the available listings (price/wear/stickers/etc.) for a specific item type. Identify the item with either `itemId` or its exact `marketHashName` (itemId wins when both are sent). Optionally filter by Doppler `phase` (e.g. 'Ruby'), `delivery`, and a `floatMin`/`floatMax` wear range. Pass the resulting item ids to /secure/buy.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":256,"description":"Skinshark catalog item id (from market suggestions or /secure/prices). Provide this OR marketHashName; when both are sent, itemId wins."},"required":false,"description":"Skinshark catalog item id (from market suggestions or /secure/prices). Provide this OR marketHashName; when both are sent, itemId wins.","name":"itemId","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":256,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied. CS2 only."},"required":false,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied. CS2 only.","name":"marketHashName","in":"query"},{"schema":{"type":"string","enum":["any","standard","instant"],"default":"any"},"required":false,"name":"delivery","in":"query"},{"schema":{"type":"string","enum":["Phase 1","Phase 2","Phase 3","Phase 4","Ruby","Sapphire","Black Pearl","Emerald"],"description":"Doppler phase to list (e.g. 'Ruby'). Returns only that phase's listings. CS2 only."},"required":false,"description":"Doppler phase to list (e.g. 'Ruby'). Returns only that phase's listings. CS2 only.","name":"phase","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Lower bound on the item float/wear value (0-1)."},"required":false,"description":"Lower bound on the item float/wear value (0-1).","name":"floatMin","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Upper bound on the item float/wear value (0-1)."},"required":false,"description":"Upper bound on the item float/wear value (0-1).","name":"floatMax","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"perPage","in":"query"}],"responses":{"200":{"description":"Available listings","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/trades":{"get":{"summary":"List merchant self-trades","description":"Cursor-paginated history of trades initiated via /secure/buy and /secure/sell. End-user client trades are NOT included here - use the merchant module for combined history.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["deposit","withdraw"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","default":"730"},"required":false,"name":"game","in":"query"}],"responses":{"200":{"description":"Paginated self-trade history","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/trades/{tradeId}":{"get":{"summary":"Get a trade by id or externalId","description":"Returns the full record (status, items, collateral, bot info, error) for a trade. `tradeId` accepts either the internal trade id or the `externalId` you supplied at creation. Comma-separate up to 100 ids/externalIds (id1,id2,id3) to fetch several in one call — useful for polling multiple pending withdrawals. With one ref the response is a single trade (404 if not found); with multiple it is an array of the trades that resolved (refs that don't match are simply omitted, no 404). Scoped to the calling merchant: returns both your own /secure/* trades and trades belonging to your clients.","tags":["Trading"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Internal trade id or your externalId. Comma-separate up to 100 (id1,id2,id3) to fetch multiple — the response is then an array."},"required":true,"description":"Internal trade id or your externalId. Comma-separate up to 100 (id1,id2,id3) to fetch multiple — the response is then an array.","name":"tradeId","in":"path"}],"responses":{"200":{"description":"A single trade (one ref) or an array of trades (comma-separated refs)","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}}]}},"required":["requestId","success","data"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/inventory":{"get":{"summary":"Get client Steam inventory","description":"Fetches the authenticated client's Steam inventory with pricing, search, filtering, and pagination. Inventory is cached for 15 minutes unless refresh=true. Includes collateral calculation.","tags":["Client"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"default":false},"required":false,"name":"refresh","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"default":false,"description":"Return only items accepted for deposit (offer.accepted = true)"},"required":false,"description":"Return only items accepted for deposit (offer.accepted = true)","name":"acceptedOnly","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":730},"required":false,"name":"game","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"sort","in":"query"},{"schema":{"type":["number","null"]},"required":false,"name":"minPrice","in":"query"},{"schema":{"type":["number","null"]},"required":false,"name":"maxPrice","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":["integer","null"],"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Client inventory with items, count, and collateral","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"inventory":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"count":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"},"collateral":{"type":"number","description":"Available collateral in USD"}},"required":["inventory","count","updatedAt","collateral"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"424":{"description":"Failed Dependency - Steam could not serve the request (inventory fetch failed, temporarily unavailable, or rate-limited upstream). The caller is not at fault; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trades":{"get":{"summary":"Get client trade history","description":"Returns the authenticated client's trade history with pagination. Can be filtered by trade type (`deposit`/`withdraw`) and game.","tags":["Client"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["deposit","withdraw"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","default":"730"},"required":false,"name":"game","in":"query"}],"responses":{"200":{"description":"Paginated trade history","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/market/suggestions":{"get":{"summary":"Marketplace search suggestions","description":"Returns search-as-you-type suggestions for marketplace items. CS2 only (Skinshark-backed). Pass a returned id as itemId to /client/market/item to fetch listings.","tags":["Client"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100},"required":true,"name":"q","in":"query"}],"responses":{"200":{"description":"Search suggestions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Catalog item id, pass it as itemId to /client/market/item"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"},"rarity":{"type":"string"},"rarityColor":{"type":"string"},"itemType":{"type":"string"}},"required":["id","marketHashName","iconUrl"]}}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"424":{"description":"Failed Dependency - Steam could not serve the request (inventory fetch failed, temporarily unavailable, or rate-limited upstream). The caller is not at fault; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/market":{"get":{"summary":"Browse marketplace items","description":"Search and paginate the merchant marketplace. CS2 returns a default listing slice; Rust returns the full RustSkins marketplace. Filterable by search term, sort, and price range.","tags":["Client"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"integer","exclusiveMinimum":0,"default":730},"required":false,"name":"game","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","enum":["relevance","priceAsc","priceDesc","nameAsc","nameDesc"]},"required":false,"name":"sort","in":"query"},{"schema":{"type":["number","null"],"minimum":0},"required":false,"name":"minPrice","in":"query"},{"schema":{"type":["number","null"],"minimum":0},"required":false,"name":"maxPrice","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","default":50},"required":false,"name":"perPage","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}],"default":false,"description":"Sandbox flag. When true, every returned item is stamped with instant delivery, a placeholder preview token, and a synthetic holding bot so integrators can see the full item shape on cheap listings."},"required":false,"description":"Sandbox flag. When true, every returned item is stamped with instant delivery, a placeholder preview token, and a synthetic holding bot so integrators can see the full item shape on cheap listings.","name":"development","in":"query"}],"responses":{"200":{"description":"Marketplace search results","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"count":{"type":"integer"}},"required":["items","count"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/market/item":{"get":{"summary":"Get marketplace listings for one item","description":"Returns the available listings (price/wear/stickers/etc.) for a specific item type. CS2 only. Identify the item with either an `itemId` (from /client/market/suggestions or /client/market) or its exact `marketHashName` (itemId wins when both are sent). Optionally filter by Doppler `phase` (e.g. 'Ruby'), `delivery`, and a `floatMin`/`floatMax` wear range.","tags":["Client"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":256,"description":"Skinshark catalog item id (from market suggestions or /secure/prices). Provide this OR marketHashName; when both are sent, itemId wins."},"required":false,"description":"Skinshark catalog item id (from market suggestions or /secure/prices). Provide this OR marketHashName; when both are sent, itemId wins.","name":"itemId","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":256,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied. CS2 only."},"required":false,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied. CS2 only.","name":"marketHashName","in":"query"},{"schema":{"type":"string","enum":["any","standard","instant"],"default":"any"},"required":false,"name":"delivery","in":"query"},{"schema":{"type":"string","enum":["Phase 1","Phase 2","Phase 3","Phase 4","Ruby","Sapphire","Black Pearl","Emerald"],"description":"Doppler phase to list (e.g. 'Ruby'). Returns only that phase's listings. CS2 only."},"required":false,"description":"Doppler phase to list (e.g. 'Ruby'). Returns only that phase's listings. CS2 only.","name":"phase","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Lower bound on the item float/wear value (0-1)."},"required":false,"description":"Lower bound on the item float/wear value (0-1).","name":"floatMin","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Upper bound on the item float/wear value (0-1)."},"required":false,"description":"Upper bound on the item float/wear value (0-1).","name":"floatMax","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"perPage","in":"query"}],"responses":{"200":{"description":"Available listings","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/crypto/deposit-address":{"get":{"summary":"Get the client's crypto deposit address","description":"Returns the end user's permanent USDT/USDC deposit address on the chosen chain and creates it on the first call. The address never changes and can be reused for every deposit. On Solana each token has its own account, opened on request: pass `token` (default USDC, ignored on other chains) for the token the end user is about to send. The first call answers `pending` with no address, poll until it is `active` and `tokens` lists that token, and call again before each later deposit because an emptied account is closed. Returns ONCHAIN_ADDRESS_CAPACITY (503) when the merchant has too many Solana accounts open. Only a listed token on the listed network is credited, and a deposit under `minDepositCents` is not credited. A cleared deposit is credited to the merchant balance and announced with a `crypto_deposit` webhook carrying the `steamId`; crediting the end user is the merchant's side. Available to verified merchants.","tags":["Crypto"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string","enum":["ETH","BSC","SOL"]},"required":true,"name":"chain","in":"query"},{"schema":{"type":"string","enum":["USDT","USDC"],"default":"USDC"},"required":false,"name":"token","in":"query"}],"responses":{"200":{"description":"Deposit address","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"steamId":{"type":"string"},"chain":{"type":"string","enum":["ETH","BSC","SOL"]},"network":{"type":"string"},"testnet":{"type":"boolean"},"status":{"type":"string","enum":["active","pending","paused"]},"address":{"type":["string","null"]},"tokenAccount":{"type":["string","null"]},"tokens":{"type":"array","items":{"type":"object","properties":{"token":{"type":"string","enum":["USDT","USDC"]},"contract":{"type":"string"},"decimals":{"type":"integer"}},"required":["token","contract","decimals"]}},"minDepositCents":{"type":"integer"},"minConfirmations":{"type":"integer"},"explorerUrl":{"type":["string","null"]}},"required":["steamId","chain","network","testnet","status","address","tokenAccount","tokens","minDepositCents","minConfirmations","explorerUrl"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"503":{"description":"Service Unavailable - maintenance mode","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/crypto/deposits":{"get":{"summary":"List the client's crypto deposits","description":"Lists the end user's native deposits, newest first. Pass `nextBefore` back as `before` for the next page.","tags":["Crypto"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"Deposits page","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"deposits":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_deposit"]},"status":{"type":"string","enum":["pending","completed","failed","frozen","refunded","below_minimum"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"from":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","cryptoAmount","address","txHash","from","createdAt","updatedAt","completedAt"]}},"nextBefore":{"type":["string","null"]}},"required":["deposits","nextBefore"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/crypto/withdraw":{"post":{"summary":"Withdraw crypto to the client's address","description":"Sends USDT or USDC from the merchant balance to an address the end user chose. Because the request comes from the end user, the merchant's server is asked first: the withdrawal starts as `awaiting_approval` and a signed POST with `{ withdrawal }` goes to the merchant callback URL, the same approval call used for skin withdrawals. A 2xx answer approves it; a 4xx answer, or a body with `action: \"reject\"`, refuses it. No usable answer after three tries refuses it. The merchant must debit its own user before approving. `amountCents` is debited from the merchant balance and held at once; the end user receives `receiveCents`, which is the amount minus the flat network fee `feeCents` of the chain. `requestId` makes the call safe to retry: the same `requestId` for the same end user returns the first withdrawal and never creates a second one. Every later status change is announced with a `crypto_withdraw` webhook carrying the `steamId`; on `rejected`, `failed` and `cancelled` the full amount is back in the merchant balance. Returns ONCHAIN_CLIENT_WITHDRAW_LIMIT (403) with `details.scope` (`user` or `merchant`) and `details.remainingCents` when a daily limit is reached, ONCHAIN_CLIENT_WITHDRAW_DISABLED (503) while the feature is switched off, and INSUFFICIENT_BALANCE (400) when the merchant balance does not cover it. Large withdrawals are held for a manual review (`in_review`). Available to verified merchants.","tags":["Crypto"],"security":[{"ClientToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"chain":{"type":"string","enum":["ETH","BSC","SOL"]},"token":{"type":"string","enum":["USDT","USDC"]},"address":{"type":"string","minLength":26,"maxLength":64},"amountCents":{"type":"integer","exclusiveMinimum":0,"maximum":100000000},"requestId":{"type":"string","minLength":8,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["chain","token","address","amountCents","requestId"]}}}},"responses":{"201":{"description":"Withdrawal created","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_withdraw"]},"status":{"type":"string","enum":["awaiting_approval","in_review","approved","sent","completed","failed","rejected","cancelled"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"feeCents":{"type":"integer"},"receiveCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","feeCents","receiveCents","cryptoAmount","address","txHash","reason","createdAt","updatedAt","completedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"409":{"description":"Conflict - the resource is in a state that forbids the request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"503":{"description":"Service Unavailable - maintenance mode","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/crypto/withdrawals":{"get":{"summary":"List the client's crypto withdrawals","description":"Lists the end user's crypto withdrawals, newest first. Pass `nextBefore` back as `before` for the next page.","tags":["Crypto"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"Withdrawals page","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"withdrawals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_withdraw"]},"status":{"type":"string","enum":["awaiting_approval","in_review","approved","sent","completed","failed","rejected","cancelled"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"feeCents":{"type":"integer"},"receiveCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","feeCents","receiveCents","cryptoAmount","address","txHash","reason","createdAt","updatedAt","completedAt"]}},"nextBefore":{"type":["string","null"]}},"required":["withdrawals","nextBefore"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/crypto/withdraw":{"post":{"summary":"Withdraw crypto to a client's address","description":"Sends USDT or USDC from the merchant balance to an end user's address. The request comes from the merchant's own server, so no approval callback is made: debit your user first, then call this. `amountCents` is debited from the merchant balance and held at once; the end user receives `receiveCents`, which is the amount minus the flat network fee `feeCents` of the chain. `requestId` makes the call safe to retry: the same `requestId` for the same end user returns the first withdrawal and never creates a second one. Every later status change is announced with a `crypto_withdraw` webhook carrying the `steamId`; on `rejected`, `failed` and `cancelled` the full amount is back in the merchant balance. Returns ONCHAIN_CLIENT_WITHDRAW_LIMIT (403) with `details.scope` (`user` or `merchant`) and `details.remainingCents` when a daily limit is reached, ONCHAIN_CLIENT_WITHDRAW_DISABLED (503) while the feature is switched off, and INSUFFICIENT_BALANCE (400) when the merchant balance does not cover it. Large withdrawals are held for a manual review (`in_review`). Available to verified merchants. Requires CORE_ACCESS scope.","tags":["Crypto"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"chain":{"type":"string","enum":["ETH","BSC","SOL"]},"token":{"type":"string","enum":["USDT","USDC"]},"address":{"type":"string","minLength":26,"maxLength":64},"amountCents":{"type":"integer","exclusiveMinimum":0,"maximum":100000000},"requestId":{"type":"string","minLength":8,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"steamId":{"type":"string","pattern":"^76561\\d{12}$"}},"required":["chain","token","address","amountCents","requestId","steamId"]}}}},"responses":{"201":{"description":"Withdrawal created","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_withdraw"]},"status":{"type":"string","enum":["awaiting_approval","in_review","approved","sent","completed","failed","rejected","cancelled"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"feeCents":{"type":"integer"},"receiveCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","feeCents","receiveCents","cryptoAmount","address","txHash","reason","createdAt","updatedAt","completedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"409":{"description":"Conflict - the resource is in a state that forbids the request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"503":{"description":"Service Unavailable - maintenance mode","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/crypto/withdrawals":{"get":{"summary":"List a client's crypto withdrawals","description":"Lists the end user's crypto withdrawals, newest first. Pass `nextBefore` back as `before` for the next page. Requires CORE_ACCESS scope.","tags":["Crypto"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","pattern":"^76561\\d{12}$"},"required":true,"name":"steamId","in":"query"}],"responses":{"200":{"description":"Withdrawals page","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"withdrawals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_withdraw"]},"status":{"type":"string","enum":["awaiting_approval","in_review","approved","sent","completed","failed","rejected","cancelled"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"feeCents":{"type":"integer"},"receiveCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","feeCents","receiveCents","cryptoAmount","address","txHash","reason","createdAt","updatedAt","completedAt"]}},"nextBefore":{"type":["string","null"]}},"required":["withdrawals","nextBefore"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/crypto/deposit-address":{"get":{"summary":"Get a client's crypto deposit address","description":"Returns the end user's permanent USDT/USDC deposit address on the chosen chain and creates it on the first call. The address never changes and can be reused for every deposit. On Solana each token has its own account, opened on request: pass `token` (default USDC, ignored on other chains) for the token the end user is about to send. The first call answers `pending` with no address, poll until it is `active` and `tokens` lists that token, and call again before each later deposit because an emptied account is closed. Returns ONCHAIN_ADDRESS_CAPACITY (503) when the merchant has too many Solana accounts open. Only a listed token on the listed network is credited, and a deposit under `minDepositCents` is not credited. A cleared deposit is credited to the merchant balance and announced with a `crypto_deposit` webhook carrying the `steamId`; crediting the end user is the merchant's side. Available to verified merchants. Requires CORE_ACCESS scope.","tags":["Crypto"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["ETH","BSC","SOL"]},"required":true,"name":"chain","in":"query"},{"schema":{"type":"string","enum":["USDT","USDC"],"default":"USDC"},"required":false,"name":"token","in":"query"},{"schema":{"type":"string","pattern":"^76561\\d{12}$"},"required":true,"name":"steamId","in":"query"}],"responses":{"200":{"description":"Deposit address","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"steamId":{"type":"string"},"chain":{"type":"string","enum":["ETH","BSC","SOL"]},"network":{"type":"string"},"testnet":{"type":"boolean"},"status":{"type":"string","enum":["active","pending","paused"]},"address":{"type":["string","null"]},"tokenAccount":{"type":["string","null"]},"tokens":{"type":"array","items":{"type":"object","properties":{"token":{"type":"string","enum":["USDT","USDC"]},"contract":{"type":"string"},"decimals":{"type":"integer"}},"required":["token","contract","decimals"]}},"minDepositCents":{"type":"integer"},"minConfirmations":{"type":"integer"},"explorerUrl":{"type":["string","null"]}},"required":["steamId","chain","network","testnet","status","address","tokenAccount","tokens","minDepositCents","minConfirmations","explorerUrl"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"503":{"description":"Service Unavailable - maintenance mode","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/secure/crypto/deposits":{"get":{"summary":"List a client's crypto deposits","description":"Lists the end user's native deposits, newest first. Pass `nextBefore` back as `before` for the next page. Requires CORE_ACCESS scope.","tags":["Crypto"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","pattern":"^76561\\d{12}$"},"required":true,"name":"steamId","in":"query"}],"responses":{"200":{"description":"Deposits page","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"deposits":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["crypto_deposit"]},"status":{"type":"string","enum":["pending","completed","failed","frozen","refunded","below_minimum"]},"steamId":{"type":"string"},"chain":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"amountCents":{"type":"integer"},"cryptoAmount":{"type":"string"},"address":{"type":"string"},"txHash":{"type":["string","null"]},"from":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","type","status","steamId","chain","token","amount","amountCents","cryptoAmount","address","txHash","from","createdAt","updatedAt","completedAt"]}},"nextBefore":{"type":["string","null"]}},"required":["deposits","nextBefore"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trading/deposit":{"post":{"summary":"Initiate a skin deposit","description":"Initiates a deposit trade where the client sends skins to the platform. Each item must include the itemId from inventory and the agreed price (USD). Supports instant crediting (isInstant=true) where eligible; defaults to a full hold (isInstant=false). Uses distributed locks to prevent race conditions per Steam user.","tags":["Deposits"],"security":[{"ClientToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256},"price":{"type":"number","exclusiveMinimum":0},"amount":{"type":"integer","minimum":1,"maximum":10000,"default":1}},"required":["itemId","price"]},"minItems":1,"maxItems":250},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128},"isInstant":{"type":"boolean","default":false}},"required":["items"],"additionalProperties":false}}}},"responses":{"200":{"description":"Deposit trade initiated","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"relatedTrades":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]},"description":"Additional trades created when a basket is split into multiple trade offers. Each settles independently and emits its own webhooks."}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"424":{"description":"Failed Dependency - Steam could not serve the request (inventory fetch failed, temporarily unavailable, or rate-limited upstream). The caller is not at fault; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trading/withdraw":{"post":{"summary":"Initiate a skin withdrawal","description":"Initiates a withdrawal trade where the client receives skins from the platform. Each item must include the itemId from the prices endpoint and the agreed price (USD). Maximum 50 items per withdrawal. Price is validated against current offers. Optional `autoCancel` (minutes, 30-720, default 30; 720 disables) cancels still-undelivered items automatically after the period, with refunds settling via the trade webhook. CS2 only.","tags":["Withdrawals"],"security":[{"ClientToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256},"price":{"type":"number","exclusiveMinimum":0,"maximum":100000,"description":"Price you quoted the end user. A lower current price is accepted and charged instead; a higher one is rejected unless it fits maxPrice or slippageBps."},"maxPrice":{"type":"number","exclusiveMinimum":0,"maximum":100000,"description":"Highest price you will pay for this item. Overrides slippageBps. Omit to reject any rise above price."},"externalId":{"type":"string","minLength":1,"maxLength":128,"description":"Your own reference for this item. Cancel accepts it in place of the item id."}},"required":["itemId","price"]},"minItems":1,"maxItems":50},"slippageBps":{"type":"integer","minimum":0,"maximum":2000,"description":"Upward tolerance in basis points applied to every item lacking maxPrice (100 = 1%). Defaults to 0."},"autoCancel":{"type":"integer","minimum":30,"maximum":720,"description":"Minutes after creation to automatically cancel still-undelivered items (30-720). Defaults to 30; 720 disables auto-cancel. CS2 only."},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128}},"required":["items"],"additionalProperties":false}}}},"responses":{"200":{"description":"Withdrawal trade initiated","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trading/withdraw/quick":{"post":{"summary":"Initiate a quick skin withdrawal","description":"Buys the N cheapest listings of a single item at or below a per-unit ceiling, instead of naming specific listings. Available for CS2 and Rust. Identify the item with either `itemId` or its exact `marketHashName` (itemId wins when both are sent); the per-unit `maxPrice` (fee-inclusive, gross) and `itemId` come from /secure/prices. `amount` is the quantity (1-200) and `delivery` is standard or instant. Optionally pin a Doppler `phase` (e.g. 'Ruby') to buy only that phase, priced against the phase floor for the requested delivery mode; phase and instant delivery are CS2-only. The trade starts empty and locks the worst-case total; the filled listings (which may be fewer than requested) and the refund of any unfilled / below-ceiling remainder settle asynchronously via the trade webhook. Optional `autoCancel` (minutes, 30-720, default 30; 720 disables) cancels still-undelivered items automatically after the period, with refunds settling via the trade webhook. CS2 only.","tags":["Withdrawals"],"security":[{"ClientToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"itemId":{"type":"string","minLength":5,"maxLength":256,"description":"Item id from /secure/prices (Skinshark catalog id for CS2, listing id for Rust). Provide this OR marketHashName; when both are sent, itemId wins."},"marketHashName":{"type":"string","minLength":1,"maxLength":256,"description":"Exact market hash name (e.g. 'AK-47 | Redline (Field-Tested)'), resolved to a catalog item id. Ignored when itemId is supplied."},"maxPrice":{"type":"number","exclusiveMinimum":0,"maximum":100000},"amount":{"type":"integer","minimum":1,"maximum":200},"delivery":{"type":"string","enum":["standard","instant"],"default":"standard"},"phase":{"type":"string","enum":["Phase 1","Phase 2","Phase 3","Phase 4","Ruby","Sapphire","Black Pearl","Emerald"],"description":"Doppler phase to buy (e.g. 'Ruby'). Priced against the phase floor for the requested delivery mode."},"autoCancel":{"type":"integer","minimum":30,"maximum":720,"description":"Minutes after creation to automatically cancel still-undelivered items (30-720). Defaults to 30; 720 disables auto-cancel. CS2 only."},"game":{"type":"string","default":"730"},"externalId":{"type":"string","maxLength":128},"externalIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"description":"Your own reference per requested unit, one per item, applied in order. Must hold exactly `amount` entries. Cancel accepts them in place of the item id."}},"required":["maxPrice","amount"],"additionalProperties":false}}}},"responses":{"200":{"description":"Quick withdrawal trade initiated (items settle via webhook)","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["deposit","withdraw"]},"source":{"type":"string","enum":["client","self"],"description":"Trade origin: \"client\" (end-user flow) or \"self\" (merchant self-trade)"},"externalId":{"type":"string"},"externalClientUserId":{"type":"string"},"merchantId":{"type":"string"},"clientUserId":{"type":"string"},"clientTradeUrl":{"type":"string"},"clientSteamID":{"type":"string"},"offerID":{"type":"string","description":"Steam trade offer id. Present once the offer is sent."},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Trade status. In-flight: initiated, pending, active, hold. Terminal: completed, failed, canceled, declined, reverted. Deposit flow: initiated → pending (offer created, awaiting bot confirmation) → active (offer confirmed, offerID present) → hold → completed. Withdraw flow: initiated → pending → active → hold → completed."},"game":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"On CS2 withdraw items this is the listing id you quoted, unchanged for the item's whole life (the delivered assetid arrives under assetId); cancel endpoints accept it alongside your externalId. On inventory and deposit items it is the encoded item id."},"itemId":{"type":"string","description":"The parent catalog item this listing belongs to (hex, e.g. \"0010f8d48278ccb8\") — the same id you pass to `/market/item`, while `id` above identifies the individual listing. Present on CS2 `GET /market` rows only: `/market/item` omits it because you named the item in the request, and it is never present on Rust, inventory, deposit or withdraw items."},"externalId":{"type":"string","description":"Your own per-item reference, when you supplied one at buy time. Cancel accepts it in place of id. Omitted on stacked Rust rows, which stand for several items at once."},"assetId":{"type":"string","description":"Raw Steam assetid. Always present on inventory listings and deposit trade items. Omitted on withdraw items until the item lands in the recipient's Steam inventory."},"appid":{"type":"integer"},"name":{"type":"string","description":"Omitted on bare withdraw items where AssetPay has no Steam-side metadata yet"},"marketHashName":{"type":"string"},"type":{"type":"string"},"iconUrl":{"type":"string"},"tradable":{"type":"boolean"},"amount":{"type":"number"},"status":{"type":"string","enum":["initiated","pending","active","hold","completed","failed","canceled","declined","reverted"],"description":"Per-item status (withdrawals only)"},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED"],"description":"Failure code for a failed withdraw item (withdrawals only)"},"marketPrice":{"type":"number","description":"Market reference price in USD"},"offer":{"type":"object","properties":{"price":{"type":"number","description":"Offer price in USD"},"delivery":{"type":"string","enum":["standard","instant"],"description":"Skinshark delivery mode"},"maxAmount":{"type":"number"},"accepted":{"type":"boolean"}},"required":["price"]},"exterior":{"type":"string"},"rarity":{"type":"string"},"color":{"type":"string"},"wear":{"type":"string"},"paintSeed":{"type":"integer"},"previewToken":{"type":"string","description":"Steam inspect/preview token for rendering the item's in-game preview."},"doppler":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"},"paintIndex":{"type":"integer"}},"required":["name"]},"fade":{"type":"object","properties":{"percentage":{"type":"number"}},"required":["percentage"]},"hardened":{"type":"object","properties":{"status":{"type":"integer"},"name":{"type":"string"}},"required":["status","name"]},"stickers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"slot":{"type":"integer"},"wear":{"type":"number"},"iconUrl":{"type":"string"}},"required":["name","slot","iconUrl"]}},"charm":{"type":"object","properties":{"name":{"type":"string"},"marketHashName":{"type":"string"},"iconUrl":{"type":"string"}},"required":["name","iconUrl"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"],"description":"Holding bot identity. Present on internal-pool marketplace items."}},"required":["id","appid","tradable"]}},"totalPrice":{"type":"number","description":"Total price in USD"},"preCredit":{"type":"number","description":"Instant credit amount in USD"},"pendingCredit":{"type":"number","description":"Amount held for hold period in USD"},"isInstant":{"type":"boolean","description":"Whether instant crediting was requested"},"collateral":{"type":"object","properties":{"merchant":{"type":"number"},"provider":{"type":"number"}},"required":["merchant","provider"]},"holdEndDate":{"type":"string","format":"date-time"},"revertedBy":{"type":"string","enum":["supplier","user"]},"botInfo":{"type":"object","properties":{"name":{"type":"string"},"avatar":{"type":"string"},"joined":{"type":"string","format":"date-time"},"steamId":{"type":"string"}},"required":["name"]},"error":{"type":"string","enum":["LISTING_UNAVAILABLE","NO_LISTING_AT_PRICE","PRICE_CHANGED","TRADE_URL_INVALID","STEAM_ACCOUNT_RESTRICTED","BUYER_TRADE_RESTRICTED","OFFER_NOT_ACCEPTED","MARKET_UNAVAILABLE","PURCHASE_FAILED","USER_TRADE_RESTRICTED","USER_INVENTORY_PRIVATE","USER_ESCROW","USER_NOT_FOUND","SERVICE_UNAVAILABLE","MERCHANT_REJECTED","APPROVAL_TIMEOUT"],"description":"Trade-level failure reason, omitted when there is none. Withdraw: set only when the whole trade failed with one shared cause."},"activeAt":{"type":"string","format":"date-time","description":"When the trade first became active (the trade offer went live at the user). Absent until then."},"autoCancelAt":{"type":"string","format":"date-time","description":"When items the seller has not yet sent will be canceled automatically. Items already offered to the user or in Steam hold are never auto-canceled. Absent when auto-cancel is disabled or for Rust withdrawals."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","type","source","merchantId","clientUserId","clientTradeUrl","clientSteamID","status","game","items","totalPrice","createdAt","updatedAt"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trading/withdraw/{tradeId}/items/{itemId}/cancel":{"post":{"summary":"Cancel an undelivered withdrawal item","description":"Requests cancellation of a single undelivered withdrawal item. Skinshark (CS2) items only - Rust and internal-sourced items have no provider cancel and return TRADE_CANCEL_UNSUPPORTED. An item must be at least 30 minutes old and not yet terminal. On success the refund flows back via the trade webhook; the response only confirms the cancellation was accepted.","tags":["Withdrawals"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Internal trade id or the externalId supplied at creation."},"required":true,"description":"Internal trade id or the externalId supplied at creation.","name":"tradeId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":128,"description":"The item's `id`, or the `externalId` you supplied for it at buy time."},"required":true,"description":"The item's `id`, or the `externalId` you supplied for it at buy time.","name":"itemId","in":"path"}],"responses":{"200":{"description":"Cancellation accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"tradeId":{"type":"string","format":"uuid"},"itemId":{"type":"string","format":"uuid"},"externalId":{"type":"string"},"status":{"type":"string","enum":["cancelled"]}},"required":["tradeId","itemId","status"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/trading/withdraw/{tradeId}/cancel":{"post":{"summary":"Cancel every undelivered item in a withdrawal","description":"Requests cancellation of every still-cancellable item in the trade. Skinshark (CS2) items only - Rust and internal-sourced items have no provider cancel and return TRADE_CANCEL_UNSUPPORTED. An item must be at least 30 minutes old and not yet terminal. On success the refund flows back via the trade webhook; the response only confirms the cancellation was accepted. Best effort: a partial result is still a 200, with a per-item status and reason, so check the body rather than the status code.","tags":["Withdrawals"],"security":[{"ClientToken":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Internal trade id or the externalId supplied at creation."},"required":true,"description":"Internal trade id or the externalId supplied at creation.","name":"tradeId","in":"path"}],"responses":{"200":{"description":"Per-item cancellation outcomes","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"tradeId":{"type":"string","format":"uuid"},"requested":{"type":"integer","description":"Items the provider considered cancellable"},"cancelled":{"type":"integer"},"failed":{"type":"integer"},"items":{"type":"array","items":{"type":"object","properties":{"itemId":{"type":"string"},"externalId":{"type":"string"},"status":{"type":"string","enum":["cancelled","failed"]},"reason":{"type":"string","description":"Stable error key when the cancel was refused, e.g. TRADE_CANCEL_TOO_SOON or TRADE_NOT_CANCELLABLE."}},"required":["itemId","status"]}}},"required":["tradeId","requested","cancelled","failed","items"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/verification/start":{"post":{"summary":"Start identity verification","description":"Initiates a Signicat PictureID verification (document scan + selfie). Returns a `captureUrl` the client should open in a browser or webview to complete the capture. An optional `email` can be provided which is stored on the client record for future identity linking.\n\n**Limits:**\n- Returns `VERIFICATION_ALREADY_VERIFIED` if the account is already verified (level >= 1).\n- Returns `VERIFICATION_IN_PROGRESS` if an active process was created within the last 30 minutes.\n- Returns `VERIFICATION_NOT_AVAILABLE` if Signicat credentials are not configured.","tags":["Verification"],"security":[{"ClientToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Verification started  open `captureUrl` in the client.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"captureUrl":{"type":"string","description":"URL to redirect/open for document + selfie capture"},"dossierId":{"type":"string","description":"Signicat dossier ID"}},"required":["captureUrl","dossierId"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"503":{"description":"Service Unavailable - maintenance mode","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/verification/status":{"get":{"summary":"Get verification status","description":"Returns the current verification level of the authenticated client, their associated email, the most recent Signicat process (if any), and the linked verified identity (if any).","tags":["Verification"],"security":[{"ClientToken":[]}],"responses":{"200":{"description":"Current verification status","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"verificationLevel":{"type":"integer","minimum":0,"description":"Current verification level (0 = none, 1 = picture_id)"},"email":{"type":["string","null"],"format":"email","description":"Email address associated with this account"},"latestProcess":{"type":["object","null"],"properties":{"dossierId":{"type":"string","description":"Signicat dossier ID"},"processId":{"type":["string","null"],"description":"Signicat process ID"},"captureUrl":{"type":"string","description":"URL the client should open to complete document capture"},"status":{"type":"string","enum":["CREATED","CAPTURE_PENDING","PROCESSING","ACCEPTED","REJECTED","ERROR","EXPIRED"]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["dossierId","processId","captureUrl","status","createdAt","completedAt"],"description":"Most recent verification attempt, or null if none"},"linkedIdentity":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"Verified identity ID"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"documentCountry":{"type":["string","null"],"description":"ISO 3166-1 alpha-3 country code of the document"},"linkedAt":{"type":"string","format":"date-time"}},"required":["id","firstName","lastName","documentCountry","linkedAt"],"description":"Verified identity linked to this account, or null if not yet verified"}},"required":["verificationLevel","email","latestProcess","linkedIdentity"]}},"required":["requestId","success","data"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/client/verification/link":{"post":{"summary":"Link account to existing identity","description":"Links the authenticated client's account to an existing verified identity via email match. Use this after a successful verification completes for another account with the same email.\n\nNo request body is needed  the identity is looked up automatically by the client's email address (set during the `/start` call).\n\n**Requirements:**\n- The client must have an email set on their account (provided during `/start`).\n- A verified identity with a matching email must exist (case-insensitive).\n- The identity must not be banned.\n- The identity must not have reached its maximum linked account limit.\n\nOn success, the account's `verificationLevel` is immediately upgraded to `1` (picture_id).","tags":["Verification"],"security":[{"ClientToken":[]}],"responses":{"200":{"description":"Account successfully linked to the verified identity","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"linked":{"type":"boolean","enum":[true]}},"required":["linked"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/v1/wallets/me/balance":{"get":{"summary":"Get merchant wallet balance","description":"Returns the authenticated merchant's wallet in USD. balance is spendable now; pendingBalance holds uncleared deposits and funds locked for in-flight withdrawals; escrowBalance holds skin deposits still in their hold period.","tags":["Wallet"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Merchant balances","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"balance":{"type":"number","description":"Available balance in USD"},"pendingBalance":{"type":"number","description":"Pending (uncleared) balance in USD"},"escrowBalance":{"type":"number","description":"Escrowed balance held for in-flight trades, in USD"},"currency":{"type":"string"}},"required":["balance","pendingBalance","escrowBalance","currency"]}},"required":["requestId","success","data"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/v1/ledger/transactions":{"get":{"summary":"List ledger transactions","description":"Wallet funding history for the authenticated merchant, newest first: deposits, withdrawals, refunds and internal transfers, plus admin credits and debits (type ADMIN_CREDIT / ADMIN_DEBIT). Trade settlements are not included. INITIATED fundings older than 24 hours are hidden. Filter by type, status and a created-at date range.","tags":["Ledger"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["DEPOSIT","WITHDRAWAL","REFUND","INTERNAL_TRANSFER"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["INITIATED","PENDING","PENDING_ADMIN","APPROVED","REJECTED","COMPLETED","FAILED","CANCELLED","REFUNDED","EXPIRED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Created at or after (ISO 8601)"},"required":false,"description":"Created at or after (ISO 8601)","name":"startDate","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Created at or before (ISO 8601)"},"required":false,"description":"Created at or before (ISO 8601)","name":"endDate","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"default":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Paginated transaction history","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"amount":{"type":"object","properties":{"usd":{"type":"number"},"crypto":{"type":"string"},"token":{"type":["string","null"]},"chain":{"type":["string","null"]}},"required":["usd","crypto","token","chain"]},"fee":{"type":"number"},"address":{"type":["string","null"]},"txnHash":{"type":["string","null"]},"timestamps":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"completed":{"type":["string","null"],"format":"date-time"},"updated":{"type":"string","format":"date-time"}},"required":["created","completed","updated"]}},"required":["id","type","status","amount","fee","address","txnHash","timestamps"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","limit","total","totalPages"]}},"required":["items","pagination"]}},"required":["requestId","success","data"]}}}},"400":{"description":"Bad Request - validation failed or invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}},"/v1/ledger/transactions/{transactionId}":{"get":{"summary":"Get transaction details","description":"Full detail for one funding (deposit, withdrawal, refund or internal transfer) owned by the authenticated merchant. Admin credit and debit ids from the transaction list are not fundings and return 404.","tags":["Ledger"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"transactionId","in":"path"}],"responses":{"200":{"description":"Transaction details","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"amount":{"type":"object","properties":{"usd":{"type":"number"},"crypto":{"type":"string"},"token":{"type":["string","null"]},"chain":{"type":["string","null"]},"exchangeRate":{"type":"string"}},"required":["usd","crypto","token","chain","exchangeRate"]},"address":{"type":["string","null"]},"txnHash":{"type":["string","null"]},"fee":{"type":"number"},"timestamps":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"completed":{"type":["string","null"],"format":"date-time"},"updated":{"type":"string","format":"date-time"},"expired":{"type":["string","null"],"format":"date-time"}},"required":["created","completed","updated","expired"]}},"required":["id","type","status","amount","address","txnHash","fee","timestamps"]}},"required":["requestId","success","data"]}}}},"401":{"description":"Unauthorized - missing or invalid credentials","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique request identifier"},"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"integer","description":"Numeric error code (see error-codes.ts)"},"key":{"type":"string","description":"Machine-readable error key"},"message":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable, for display and logs only - do not parse it. Wording changes without notice; branch on `key` or `code` instead, and read `fields` for per-field detail. On VALIDATION_FAILED each offending field is named: \"tradeurl: Trade URL must be ...\"."},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Present only on VALIDATION_FAILED. Maps the dotted path of each rejected field to why it was rejected, one entry per field. Capped at 20 entries; `message` names the first 5."}},"required":["code","key","message"]}},"required":["requestId","success","error"]}}}}}}}},"webhooks":{}}