API Documentation
Browse the CS2 skin marketplace, purchase items, manage orders, and check wallet balance programmatically. All endpoints require API Token authentication.
Overview
The TradeStation Open API provides programmatic access to the CS2 skin marketplace. You can browse available inventory, execute purchases, track order status, and manage your wallet through a RESTful JSON API.
Market
Browse skins & inventory
Catalog aggregates, then list in-stock items by hash name and filters.
Trade
Purchase items
Standard buy and quick-buy; optional price checks and idempotent keys.
Orders
Track order status
List orders with status filters and fetch a single order by number.
Wallet
Balance & transactions
Snapshot of balances plus paginated history of wallet movements.
Authentication
All requests must include your API token in the Authorization header. Tokens can be generated from your account dashboard.
Authorization: Token sst_a1b2c3d4e5f6...Token format: sst_ prefix followed by 48 hex characters. The full token is only shown once at creation time — store it securely.
Base URL
https://api.tradestation.gg/api/v1All endpoint paths in this documentation are relative to this base URL.
Response Format
Every response is wrapped in a standard envelope. The top-level code field uses TradeStation business status codes (not HTTP status codes).
{
"code": 1000,
"message": "ok",
"data": { ... }
}{
"code": 3001,
"message": "Item is not available",
"data": null
}For failed/cancelled/reversed orders, the response includes both the error code and the order data:
{
"code": 5201,
"message": "Item unavailable",
"data": {
"order_no": "T20260407143022849132",
"status": "failed",
"fail_code": 5201,
...
}
}Pagination
List endpoints use page-based pagination. Control with page and page_size query parameters.
{
"code": 1000,
"message": "ok",
"count": 142,
"page": 1,
"page_size": 10,
"total_pages": 15,
"next": 2,
"previous": null,
"data": [ ... ]
}page | integer | Page number (default: 1) |
page_size | integer | Items per page (default: 10, max: 100) |
next | integer | null | Next page number, null if last page |
previous | integer | null | Previous page number, null if first page |
Rate Limiting
Requests are rate limited per user. Exceeding the limit returns HTTP 429 with code 9003.
| Endpoint | Limit |
|---|---|
GET /market/catalog | 5 / minute |
GET /market/items | 300 / minute |
POST /market/items/batch | 60 / minute |
GET /market/items/json | 5 / minute |
POST /market/orders/buy | 300 / minute |
POST /market/orders/quick-buy | 300 / minute |
GET /wallet | 60 / minute |
GET /wallet/transactions | 60 / minute |
Status Codes
Business status codes are segmented by range. HTTP status codes are used conventionally (200, 201, 400, 401, 403, 404, 429, 500, 503).
1xxx — Success
1000 | ok |
1001 | Order already exists |
3xxx — Buy Pre-validation
3001 | Item is not available |
3006 | Too many active orders |
3007 | Order is being processed, please try again |
3008 | This external_order_no has already been used |
3009 | Insufficient balance |
4xxx — Quick Buy Pre-validation
4001 | Quick buy is currently disabled |
4002 | No available inventory for this item |
4003 | No available items found within the price limit |
5xxx — Order Lifecycle
5001 | Order not found |
5002 | Order status does not allow this operation |
5101 | Cancelled by admin |
5102 | Trade offer expired or platform cancelled |
5201 | Item unavailable |
5202 | Trade failed |
5301 | Trade offer creation failed |
5303 | Trade offer declined |
5304 | Steam unavailable |
5401 | Invalid trade URL |
5402 | Steam account trade restricted |
5403 | Steam inventory is private |
5501 | Trade reversed on Steam |
9xxx — System
9001 | Authentication required |
9002 | Permission denied |
9003 | Rate limit exceeded |
9004 | Invalid request body |
9005 | Missing required parameter |
9006 | Invalid parameter value |
9503 | Service temporarily unavailable, please retry shortly |
9999 | Internal server error |
Order Status Flow
createdpendingcompletedcreatedfailedPre-execution failure (item unavailable, insufficient balance, etc.)pendingcancelledTrade offer expired or cancelled by adminpendingfailedBuyer declined trade offer or technical failurecompletedreversedCompleted trade reversed on SteamOrders that are still waiting on buyer-side action (e.g. trade offer acceptance) will be automatically cancelled after 40 minutes. Make sure to accept the Steam trade offer within this window to avoid cancellation.
createdOrder created, executing purchase
pendingTrade offer sent, awaiting acceptance
completedTrade completed successfully
failedTrade failed permanently
cancelledCancelled by timeout or admin
reversedCompleted trade reversed on Steam
Integration Best Practices
Use external_order_no for idempotency
Always pass your own unique order reference. If a network error occurs mid-request, retrying with the same external_order_no will return the existing order (code 1001) instead of creating a duplicate.
Use max_price for price protection (quick-buy)
Prices can change between browsing and purchasing. Set max_price in the quick-buy endpoint to reject the trade if the price exceeds your limit.
Poll order status for async fulfillment
Orders transition from created → pending → completed asynchronously. Poll GET /market/orders/{order_no} to track progress. Use exponential backoff starting from 5 seconds.
Reconcile in batches with external_order_no
To check many orders at once, pass a comma-separated list to GET /market/orders?external_order_no=a,b,c (up to 50 per request, with page_size=50). The response data holds the matched orders and a top-level not_found array lists references with no matching order — diff it against your input to reconcile efficiently instead of polling each order individually.
Handle 5xxx codes in order responses
Terminal order responses (failed/cancelled/reversed) return 5xxx codes at the top level. Check the code field before parsing data to handle failures gracefully.
Respect rate limits
If you receive code 9003, back off and retry after the indicated period. Persistent rate limiting violations may result in token revocation.
API Reference
Complete endpoint reference for the TradeStation Open API.
Market Endpoints Overview
Three complementary endpoints serve different use cases:
| Endpoint | Purpose | Data freshness |
|---|---|---|
/catalog | Full-sync: aggregated min_price per skin | ~3–4 min snapshot |
/items | Single skin: paginated item list with full details | Real-time |
/items/batch | Multi-skin: top 5 cheapest items per skin | Real-time |
/items/json | Bulk download: full inventory as NDJSON.gz (presigned URL). Scope required | ~3–4 min snapshot |
/market/catalogReturns the aggregated overview of every skin with available inventory in a single response. Optimized for full-sync clients — served as a pre-built gzip snapshot with ETag revalidation.
Response semantics
Unlike other Open API endpoints, this response is not wrapped in the standard envelope. The body is a gzip-compressed JSON object containing only the data array — the byte stream is served directly from a pre-built snapshot to keep TTFB at 1–3 ms even at multi-million-row scale.
Response headers
Content-Encoding | string | Always gzip. Decompress before parsing JSON. Standard HTTP clients (curl --compressed, fetch, requests) handle this transparently. |
ETag | string | Weak ETag of the current snapshot, e.g. W/"a1b2c3...". Send back as If-None-Match on the next request to revalidate. |
X-Snapshot-Built-At | string | UTC timestamp (seconds, ISO 8601, no timezone suffix) of when the snapshot was last rebuilt, e.g. 2026-04-25T10:30:00. |
X-Snapshot-Rows | integer | Number of rows contained in the snapshot. |
Cache-Control | string | private, max-age=30, must-revalidate — clients should hit the endpoint at most every 30 s and always revalidate via ETag. |
Response fields (per item, after gzip decompress)
hash_name | string | Steam market hash name |
phase | string | Phase variant (e.g. "Phase 2", "Ruby"). Empty for non-Doppler items. |
min_price | decimal | Lowest available price |
{
"data": [
{
"hash_name": "AK-47 | Redline (Field-Tested)",
"phase": "",
"min_price": "28.5000"
},
{
"hash_name": "★ Karambit | Doppler (Factory New)",
"phase": "Phase 2",
"min_price": "1523.0000"
}
]
}ETag revalidation (recommended)
Cache the ETag from the last successful response and send it as If-None-Match on subsequent calls. When the snapshot is unchanged, the server returns HTTP 304 Not Modified with no body — keeping bandwidth flat and your local copy fresh.
/market/itemsReturns all available listings sorted by price (lowest first), allowing you to compare and select the exact item to buy.
Query parameters
hash_namerequired | string | Steam market hash name (exact match) |
phase | string | Filter by phase (e.g. "Phase 1", "Sapphire") |
price_max | decimal | Maximum price filter |
page | integer | Page number (default: 1) |
page_size | integer | Items per page (default: 10, max: 100) |
Response fields (per item)
id | integer | Inventory item ID (use for purchase) |
asset_id | string | null | Steam asset ID. 64-bit number returned as a string to preserve precision (exceeds JS Number.MAX_SAFE_INTEGER); may be null for legacy rows not yet backfilled by the supplier. |
hash_name | string | Steam market hash name |
name_zh | string | Chinese name |
phase | string | Phase variant |
price | decimal | Selling price (USD, 4 decimal places) |
float_value | decimal | null | Float value (up to 18 decimal places) |
paint_seed | integer | null | Paint seed |
paint_index | integer | null | Paint index |
name_tag | string | Applied name tag |
stickers | array | Applied stickers |
charm | array | Attached charms (keychain slot) |
GET /api/v1/market/items?hash_name=Souvenir+Galil+AR+%7C+Green+Apple+(Factory+New)&page_size=2Rows are sampled from real listings for the same hash_name (IDs and stock change over time). stickers / charm drop skin_id and image_url. Some sources expose market_hash_name plus placement floats; others expose a display name only. The second list entry omits attachment bodies and uses [ ... ] as a shorthand.
{
"code": 1000,
"message": "ok",
"count": 11,
"page": 1,
"page_size": 2,
"total_pages": 6,
"next": 2,
"previous": null,
"data": [
{
"id": 40310,
"asset_id": "47543634523534789",
"hash_name": "Souvenir Galil AR | Green Apple (Factory New)",
"name_zh": "加利尔AR(纪念品) | 绿苹果 (崭新出厂)",
"phase": "",
"price": "10.2500",
"float_value": "0.034173440188169479",
"paint_seed": 780,
"paint_index": 294,
"name_tag": "",
"stickers": [
{
"name": " StarLadder(金色)| 2025年布达佩斯锦标赛",
"slot": 0,
"wear": "0"
},
{
"name": " 火车(金色)",
"slot": 2,
"wear": "0"
},
{
"name": " Natus Vincere(金色)| 2025年布达佩斯锦标赛",
"slot": 1,
"wear": "0"
},
{
"name": " FURIA(金色)| 2025年布达佩斯锦标赛",
"slot": 3,
"wear": "0"
}
],
"charm": [
{
"name": "挂件(纪念品): 2025年布达佩斯锦标赛高光时刻 | YEKINDAR对阵Natus Vincere Train精彩表现",
"pattern": null
}
]
},
{
"id": 40311,
"asset_id": "47543634523534812",
"hash_name": "Souvenir Galil AR | Green Apple (Factory New)",
"name_zh": "加利尔AR(纪念品) | 绿苹果 (崭新出厂)",
"phase": "",
"price": "10.2500",
"float_value": "0.060612890869379043",
"paint_seed": 803,
"paint_index": 294,
"name_tag": "",
"stickers": [ ... ],
"charm": [ ... ]
}
]
}/market/items/batchBatch query multiple skins at once. Returns up to 5 lowest-priced items per skin. Useful for checking availability and pricing across many skins in a single request.
When to use
Use this endpoint when you need real-time prices for multiple skins simultaneously (e.g. refreshing a watchlist, comparing prices, or pre-checking stock before bulk purchases). It queries the database directly with no caching — results are always up-to-date.
Request body
itemsrequired | array | Array of query objects (1–50 entries) |
items[].hash_namerequired | string | Steam market hash name (exact match) |
items[].phase | string | Optional phase filter (e.g. "Phase 2", "Sapphire") |
Response format
The data field is an object keyed by skin identifier. Each value is an array of up to 5 items sorted by price ascending. Skins not found or with no available stock return an empty array. Response key is hash_name when no phase is specified, or hash_name + phase (concatenated directly, no separator) when phase is present.
Item fields are identical to List Items: id, asset_id, hash_name, name_zh, phase, price, float_value, paint_seed, paint_index, name_tag, stickers, charm.
POST /api/v1/market/items/batch
Content-Type: application/json
Authorization: Token sst_a1b2c3d4e5f6...
{
"items": [
{"hash_name": "AK-47 | Redline (Field-Tested)"},
{"hash_name": "★ Karambit | Doppler (Factory New)", "phase": "Phase 2"},
{"hash_name": "Non-Existent Skin"}
]
}{
"code": 1000,
"message": "ok",
"data": {
"AK-47 | Redline (Field-Tested)": [
{
"id": 12001,
"asset_id": "47543634523534789",
"hash_name": "AK-47 | Redline (Field-Tested)",
"name_zh": "AK-47 | 红线 (久经沙场)",
"phase": "",
"price": "28.5000",
"float_value": "0.256312847137451170",
"paint_seed": 661,
"paint_index": 282,
"name_tag": "",
"stickers": [],
"charm": []
},
{
"id": 12042,
"asset_id": "47543634523534820",
"hash_name": "AK-47 | Redline (Field-Tested)",
"name_zh": "AK-47 | 红线 (久经沙场)",
"phase": "",
"price": "29.1200",
"float_value": "0.180000000000000000",
"paint_seed": 123,
"paint_index": 282,
"name_tag": "",
"stickers": [ ... ],
"charm": []
}
],
"★ Karambit | Doppler (Factory New)Phase 2": [
{
"id": 8821,
"asset_id": "47543634523534931",
"hash_name": "★ Karambit | Doppler (Factory New)",
"name_zh": "★ 爪子刀 | 多普勒 (崭新出厂)",
"phase": "Phase 2",
"price": "1523.0000",
"float_value": "0.008221340179443359",
"paint_seed": 420,
"paint_index": 418,
"name_tag": "",
"stickers": [],
"charm": []
}
],
"Non-Existent Skin": []
}
}/market/items/jsonDownload the full inventory of available items from your buyer perspective as a single newline-delimited JSON (NDJSON.gz) file. Returns a short-lived presigned S3 URL; the file itself contains all listings with buyer-specific pricing already applied.
Special permission required — contact an administrator to apply.
Response fields
download_url | string | Presigned S3 GET URL. Plain HTTP request, no auth header required. Time-limited (see expires_at). |
format | string | Always application/x-ndjson — one JSON object per line, separated by \n. |
content_encoding | string | Always gzip. Decompress before parsing. curl --compressed / Python requests handle this transparently. |
size | integer | Compressed file size in bytes. |
rows | integer | Number of items contained in the file. |
built_at | string | UTC timestamp (seconds, ISO 8601, no timezone suffix) of when the snapshot was last rebuilt. |
expires_at | string | UTC timestamp when the presigned URL expires. Request a fresh URL after this point. |
File line format (after gzip decompress)
item_id | integer | Inventory item ID (use for purchase) |
asset_id | string | null | Steam asset ID. 64-bit number returned as a string to preserve precision; null for legacy rows not yet backfilled. |
hash_name | string | Steam market hash name |
phase | string | Phase variant (empty for non-Doppler items) |
name_zh | string | Chinese name |
price | decimal | Your buyer-specific price (default fee + per-seller overrides already applied, 4-decimal precision) |
float_value | decimal | null | Item float value (skins only) |
paint_seed | integer | null | Paint seed (skins only) |
paint_index | integer | null | Paint index (skins only) |
name_tag | string | null | Custom name tag (if any) |
stickers | array | null | Applied sticker list |
keychains | array | null | Applied charm / keychain list |
GET /api/v1/market/items/json
Authorization: Token sst_a1b2c3d4e5f6...{
"code": 1000,
"message": "ok",
"data": {
"download_url": "https://s3.example.com/open-api/items/9f86d081-...ndjson.gz?X-Amz-Signature=...",
"format": "application/x-ndjson",
"content_encoding": "gzip",
"size": 124857600,
"rows": 5021847,
"built_at": "2026-05-18T00:30:00",
"expires_at": "2026-05-18T00:45:00"
}
}{"item_id":12001,"asset_id":"47543634523534789","hash_name":"AK-47 | Redline (Field-Tested)","phase":"","name_zh":"AK-47 | 红线 (久经沙场)","price":"28.5000","float_value":"0.256312847137451170","paint_seed":661,"paint_index":282,"name_tag":"","stickers":[],"keychains":[]}How to use the metadata
- NDJSON.gz lets you parse line-by-line during decompression — no need to load the whole file into memory, even at millions of rows.
built_atidentifies the snapshot version. Cache it locally and skip re-downloading when it hasn't changed. Snapshots refresh roughly every 3 minutes.size/rowslet you verify the download completed and estimate parse progress.expires_atis the presigned URL expiry — call the endpoint again to get a fresh URL (the underlying file stays the same untilbuilt_atadvances).- A 503 response means the snapshot is being built — wait for
Retry-Afterseconds and try again.
Python example: download & stream-parse
import gzip, json, time, requests
API = "https://api.tradestation.gg/api/v1"
AUTH = {"Authorization": "Token sst_a1b2c3d4e5f6..."}
def fetch_manifest():
while True:
r = requests.get(f"{API}/market/items/json", headers=AUTH, timeout=30)
if r.status_code == 200:
return r.json()["data"]
if r.status_code == 503:
time.sleep(int(r.headers.get("Retry-After", "60")))
continue
r.raise_for_status()
m = fetch_manifest()
print(f"snapshot built_at={m['built_at']} rows={m['rows']}")
# Stream download → gunzip → parse line by line (constant memory)
with requests.get(m["download_url"], stream=True, timeout=300) as r:
r.raise_for_status()
r.raw.decode_content = False
with gzip.GzipFile(fileobj=r.raw) as gz:
for line in gz:
item = json.loads(line)
# ... your analysis here, e.g. group by hash_name ...
Important: Asynchronous Fulfillment
Both buy and quick-buy are asynchronous operations. A successful response (code: 1000, status: "created") means the order has been accepted and funds have been frozen — it does not mean the Steam trade offer has been sent yet. The system will attempt to send the trade offer in the background; the order will transition to pending once the offer is dispatched successfully.
Poll GET /market/orders/{order_no} to track fulfillment progress. Orders that remain unaccepted will be automatically cancelled after 40 minutes (default timeout).
/market/orders/buyPurchase a specific inventory item by ID. The item will be delivered to your Steam trade URL.
Request body
item_idrequired | integer | Inventory item ID (from market listing) |
trade_urlrequired | string | Steam trade URL (https://steamcommunity.com/tradeoffer/new/?partner=...&token=...) |
external_order_no | string | Your external order reference (max 64 chars, must be unique per user) |
Idempotency
If a request with the same item_id (or same external_order_no) finds an existing active order, the API returns that order with code 1001 instead of creating a duplicate.
POST /api/v1/market/orders/buy
Content-Type: application/json
Authorization: Token sst_a1b2c3d4e5f6...
{
"item_id": 4821,
"trade_url": "https://steamcommunity.com/tradeoffer/new/?partner=123456&token=AbCdEf",
"external_order_no": "my-order-001"
}{
"code": 1000,
"message": "ok",
"data": {
"order_no": "T20260407143022849132",
"external_order_no": "my-order-001",
"status": "created",
"price": "28.5000",
"steam_offer_id": "",
"hash_name": "AK-47 | Redline (Field-Tested)",
"name_zh": "AK-47 | 红线 (久经沙场)",
"phase": "",
"float_value": "0.256312847137451170",
"paint_seed": 661,
"paint_index": 282,
"name_tag": "",
"stickers": [...],
"charm": [],
"fail_code": null,
"fail_reason_display": "",
"created_at": "2026-04-07T14:30:22.849132Z",
"completed_at": null,
"reversible_until": null,
"is_reversible": false
}
}/market/orders/quick-buyPurchase the lowest-priced available item for a given skin. Automatically selects the cheapest item.
Request body
hash_namerequired | string | Steam market hash name |
trade_urlrequired | string | Steam trade URL |
phase | string | Limit to a specific phase |
max_price | decimal | Maximum acceptable price — returns 4003 if no items below this price |
external_order_no | string | Your external order reference (max 64 chars) |
POST /api/v1/market/orders/quick-buy
Content-Type: application/json
Authorization: Token sst_a1b2c3d4e5f6...
{
"hash_name": "AK-47 | Redline (Field-Tested)",
"trade_url": "https://steamcommunity.com/tradeoffer/new/?partner=123456&token=AbCdEf",
"max_price": "30.0000"
}Response format is identical to the Buy Item endpoint.
/market/ordersLists your orders with optional filtering by status, external order number, and date range. Ordered by creation time descending. Each row uses the same order object shape as GET /market/orders/{order_no} (nested skin metadata plus instance fields).
Query parameters
status | string | Filter by order status: created pending completed failed cancelled reversed |
external_order_no | string | Filter by your external order reference. A single value is an exact match. Pass a comma-separated list (e.g. a,b,c) to query up to 50 references at once; exceeding 50 returns code 9006. When more than one value is supplied, the response includes a top-level not_found array listing references with no matching order on your account (independent of the status/date filters). Tip: pass page_size=50 to fetch all matches in a single page. Note: external_order_no values may not contain commas. |
start_date | string | Start date inclusive (ISO 8601 format: YYYY-MM-DD) |
end_date | string | End date inclusive (ISO 8601 format: YYYY-MM-DD) |
page | integer | Page number (default: 1) |
page_size | integer | Items per page (default: 10, max: 100) |
Date range cannot exceed 90 days. Both start_date and end_date are optional and can be used independently.
Response fields (per order)
order_no | string | TradeStation order number |
external_order_no | string | Your external reference |
status | string | Order status |
price | decimal | Transaction price |
steam_offer_id | string | Steam trade offer ID returned by the supplier on delivery. Present on successful orders; empty ("") for failed / not-yet-shipped orders. Distinct from the internal purchase order number. |
hash_name | string | Skin market hash name |
name_zh | string | Chinese name |
phase | string | Phase variant |
float_value | decimal | null | Item float (this instance) |
paint_seed | integer | null | Item paint seed |
paint_index | integer | null | Item paint index |
name_tag | string | Applied name tag on the item |
stickers | array | Stickers JSON (same storage shape as market listings) |
charm | array | Charms / keychain slot JSON |
fail_code | integer | null | Failure code (5xxx) if applicable |
fail_reason_display | string | Human-readable failure reason |
created_at | datetime | ISO 8601 timestamp |
completed_at | datetime | null | Completion time |
reversible_until | datetime | null | Reverse window cutoff (UTC). null if not completed. |
is_reversible | boolean | Whether the order is currently within the reverse window. |
GET /api/v1/market/orders?status=completed&page=1&page_size=10{
"code": 1000,
"message": "ok",
"count": 24,
"page": 1,
"page_size": 10,
"total_pages": 3,
"next": 2,
"previous": null,
"data": [
{
"order_no": "T20260415120000123456",
"external_order_no": "inv-2026-0415-001",
"status": "completed",
"price": "28.5000",
"steam_offer_id": "7654321098",
"hash_name": "AK-47 | Redline (Field-Tested)",
"name_zh": "AK-47 | 红线 (久经沙场)",
"phase": "",
"float_value": "0.256312847137451170",
"paint_seed": 661,
"paint_index": 282,
"name_tag": "",
"stickers": [
{
"slot": 0,
"wear": null,
"market_hash_name": "Sticker | iBUYPOWER (Holo) | Katowice 2014",
"offset_x": -0.08,
"offset_y": 0.02,
"rotation": null
}
],
"charm": [],
"fail_code": null,
"fail_reason_display": "",
"created_at": "2026-04-15T10:12:03.123456Z",
"completed_at": "2026-04-15T10:18:44.987654Z",
"reversible_until": "2026-04-23T07:00:00Z",
"is_reversible": true
},
{
"order_no": "T20260415104500987654",
"external_order_no": "",
"status": "pending",
"price": "120.7143",
"steam_offer_id": "",
"hash_name": "AWP | Chrome Cannon (Factory New)",
"name_zh": "AWP | 镀铬大炮 (崭新出厂)",
"phase": "",
"float_value": "0.069282613694667820",
"paint_seed": 946,
"paint_index": 1170,
"name_tag": "",
"stickers": [ ... ],
"charm": [ ... ],
"fail_code": null,
"fail_reason_display": "",
"created_at": "2026-04-15T09:45:22.100000Z",
"completed_at": null,
"reversible_until": null,
"is_reversible": false
}
]
}GET /api/v1/market/orders?external_order_no=inv-001,inv-002,inv-404&page_size=50{
"code": 1000,
"message": "ok",
"count": 2,
"page": 1,
"page_size": 50,
"total_pages": 1,
"next": null,
"previous": null,
"data": [
{ "order_no": "T20260415120000123456", "external_order_no": "inv-002", "status": "completed", ... },
{ "order_no": "T20260415104500987654", "external_order_no": "inv-001", "status": "pending", ... }
],
"not_found": ["inv-404"]
}/market/orders/{order_no}Retrieve a single order. Response body matches one element from GET /market/orders (same fields and nesting).
Path parameters
order_norequired | string | TradeStation order number or your external_order_no. The API first tries to match by system order number; if not found, it falls back to your external reference. |
Field list is identical to each object in the order list — same flat skin fields (hash_name, name_zh, phase) plus instance attributes (float_value, paint_*, name_tag, stickers, charm).
For orders in terminal states (failed, cancelled, reversed), the top-level code will be the fail_code (5xxx) instead of 1000.
GET /api/v1/market/orders/T20260415120000123456GET /api/v1/market/orders/inv-2026-0415-001{
"code": 1000,
"message": "ok",
"data": {
"order_no": "T20260415120000123456",
"external_order_no": "inv-2026-0415-001",
"status": "completed",
"price": "28.5000",
"steam_offer_id": "7654321098",
"hash_name": "AK-47 | Redline (Field-Tested)",
"name_zh": "AK-47 | 红线 (久经沙场)",
"phase": "",
"float_value": "0.256312847137451170",
"paint_seed": 661,
"paint_index": 282,
"name_tag": "",
"stickers": [
{
"slot": 0,
"wear": null,
"market_hash_name": "Sticker | iBUYPOWER (Holo) | Katowice 2014",
"offset_x": -0.08,
"offset_y": 0.02,
"rotation": null
}
],
"charm": [],
"fail_code": null,
"fail_reason_display": "",
"created_at": "2026-04-15T10:12:03.123456Z",
"completed_at": "2026-04-15T10:18:44.987654Z",
"reversible_until": "2026-04-23T07:00:00Z",
"is_reversible": true
}
}stickers / charm mirror the stored attachment JSON (same shapes as in List Items); empty arrays when none.
{
"code": 5201,
"message": "Item unavailable",
"data": {
"order_no": "T20260414083000555666",
"external_order_no": "",
"status": "failed",
"price": "15.0000",
"steam_offer_id": "",
"hash_name": "M4A4 | Howl (Field-Tested)",
"name_zh": "M4A4 | 咆哮 (久经沙场)",
"phase": "",
"float_value": "0.180000000000000000",
"paint_seed": 100,
"paint_index": 419,
"name_tag": "",
"stickers": [],
"charm": [],
"fail_code": 5201,
"fail_reason_display": "Item unavailable",
"created_at": "2026-04-14T08:30:00.000000Z",
"completed_at": null,
"reversible_until": null,
"is_reversible": false
}
}/walletReturns your current wallet balance snapshot including available, held, and frozen amounts.
Response fields
currency | string | Wallet currency (always USD) |
available | decimal | Available balance — can be used for trading and withdrawal |
held | decimal | Held balance — credited but in hold period, can trade but cannot withdraw |
frozen | decimal | Frozen balance — locked for pending orders, cannot trade or withdraw |
total | decimal | Total balance (available + held + frozen) |
tradable | decimal | Tradable balance (available + held) |
withdrawable | decimal | Withdrawable balance (available only) |
status | string | Wallet status: active or frozen |
updated_at | datetime | Last balance update time (ISO 8601) |
{
"code": 1000,
"message": "ok",
"data": {
"currency": "USD",
"available": "8997.868000",
"held": "0.000000",
"frozen": "1.066000",
"total": "8998.934000",
"tradable": "8997.868000",
"withdrawable": "8997.868000",
"status": "active",
"updated_at": "2026-04-14T16:18:46.915184Z"
}
}/wallet/transactionsLists your wallet transactions in reverse chronological order. Supports filtering by type and date range.
Query parameters
tx_type | string | Filter by transaction type: deposit withdraw trade_freeze trade_unfreeze trade_pay trade_income adjustment transfer_in transfer_out etc. |
start_date | string | Start date inclusive (ISO 8601 format: YYYY-MM-DD) |
end_date | string | End date inclusive (ISO 8601 format: YYYY-MM-DD) |
page | integer | Page number (default: 1) |
page_size | integer | Items per page (default: 100, max: 100) |
Date range cannot exceed 31 days. If only start_date is provided, end date defaults to start + 31 days (or today). If only end_date is provided, start date defaults to end − 31 days.
Response fields (per transaction)
tx_no | string | Transaction reference number |
tx_type | string | Transaction type |
amount | decimal | Change amount (positive = credit, negative = debit) |
balance_before | decimal | Available balance before this transaction |
held_before | decimal | Held balance before this transaction |
frozen_before | decimal | Frozen balance before this transaction |
balance_after | decimal | Available balance after this transaction |
held_after | decimal | Held balance after this transaction |
frozen_after | decimal | Frozen balance after this transaction |
biz_type | string | Business type (e.g. trade_freeze, adjustment) |
biz_id | string | Related business reference (e.g. order number) |
description | string | Human-readable description |
created_at | datetime | Transaction time (ISO 8601) |
GET /api/v1/wallet/transactions?start_date=2026-04-01&end_date=2026-04-14&page_size=2{
"code": 1000,
"message": "ok",
"count": 15,
"page": 1,
"page_size": 2,
"total_pages": 8,
"next": 2,
"previous": null,
"data": [
{
"tx_no": "WT2026041479108331",
"tx_type": "trade_unfreeze",
"amount": "1.660500",
"balance_before": "8996.207500",
"held_before": "0.000000",
"frozen_before": "2.726500",
"balance_after": "8997.868000",
"held_after": "0.000000",
"frozen_after": "1.066000",
"biz_type": "trade_unfreeze",
"biz_id": "T20260414154317644080",
"description": "",
"created_at": "2026-04-14T16:18:46.917017Z"
},
{
"tx_no": "WT2026041433429418",
"tx_type": "trade_freeze",
"amount": "-1.660500",
"balance_before": "8997.868000",
"held_before": "0.000000",
"frozen_before": "1.066000",
"balance_after": "8996.207500",
"held_after": "0.000000",
"frozen_after": "2.726500",
"biz_type": "trade_freeze",
"biz_id": "T20260414154317644080",
"description": "",
"created_at": "2026-04-14T15:43:17.378123Z"
}
]
}