v1Open API

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.

Request header
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

Base URL
https://api.tradestation.gg/api/v1

All 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).

Success response
{
  "code": 1000,
  "message": "ok",
  "data": { ... }
}
Error response
{
  "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:

Error with data (order failure)
{
  "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.

Paginated response
{
  "code": 1000,
  "message": "ok",
  "count": 142,
  "page": 1,
  "page_size": 10,
  "total_pages": 15,
  "next": 2,
  "previous": null,
  "data": [ ... ]
}
pageintegerPage number (default: 1)
page_sizeintegerItems per page (default: 10, max: 100)
nextinteger | nullNext page number, null if last page
previousinteger | nullPrevious page number, null if first page

Rate Limiting

Requests are rate limited per user. Exceeding the limit returns HTTP 429 with code 9003. List and detail order endpoints share one limit; buy and quick-buy share another.

EndpointLimit
GET /market/catalog5 / minute
GET /market/items300 / minute
POST /market/items/batch60 / minute
GET /market/items/json5 / minute
POST /market/orders/buy300 / minute
POST /market/orders/quick-buy300 / minute
GET /market/orders300 / minute
GET /market/orders/{order_no}300 / minute
GET /wallet60 / minute
GET /wallet/transactions60 / minute

Status Codes

Business status codes are segmented by range. HTTP status codes are used conventionally (200, 201, 400, 401, 403, 404, 405, 429, 500, 503).

1xxx — Success

1000ok
1001Order already exists

3xxx — Buy Pre-validation

3001Item is not available
3006Too many active orders
3007Order is being processed, please try again
3008This external_order_no has already been used
3009Insufficient balance
3010Item price exceeds the specified max_price
3011This item requires manual-delivery purchase permission
3012trade_url is not registered in your manual-delivery whitelist

4xxx — Quick Buy Pre-validation

4001Quick buy is currently disabled
4002No available inventory for this item
4003No available items found within the price limit

5xxx — Order Lifecycle

5001Order not found
5002Order status does not allow this operation
5101Order cancelled
5102Trade offer expired
5201Item unavailable
5202Trade failed
5301Trade offer creation failed
5303Trade offer declined
5304Steam unavailable
5401Invalid trade URL
5402Steam account trade restricted
5403Steam inventory is private
5501Trade reversed on Steam

9xxx — System

9001Authentication required
9002Permission denied
9003Rate limit exceeded
9004Invalid request body
9005Missing required parameter
9006Invalid parameter value
9008Method not allowed
9503Service temporarily unavailable, please retry shortly
9999Internal server error

Order Status Flow

Normal Flow
createdpendingcompleted
State Transitions
createdfailedPre-execution failure (item unavailable, insufficient balance, etc.)
pendingcancelledTrade offer expired or order cancelled
pendingfailedBuyer declined trade offer or technical failure
completedreversedCompleted trade reversed on Steam

Orders 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.

created

Order accepted, processing

pending

Trade offer sent, awaiting acceptance

completed

Trade completed successfully

failed

Trade failed permanently

cancelled

Cancelled (timeout or system)

reversed

Completed 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

Pass the listing price as max_price on buy or quick-buy if you want to reject repricing.

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:

EndpointPurposeData freshness
/catalogFull-sync: aggregated min_price + count per skin~3–4 min snapshot
/itemsSingle skin: paginated item list with full detailsReal-time
/items/batchMulti-skin: top 5 cheapest items per skinReal-time
/items/jsonBulk download: full item list file. Scope requiredPeriodic refresh
GET/market/catalog

Returns the aggregated overview of every skin with available inventory in a single response. Supports gzip compression and ETag revalidation for efficient full sync.

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.

Response headers

Content-EncodingstringAlways gzip. Decompress before parsing JSON. Standard HTTP clients (curl --compressed, fetch, requests) handle this transparently.
ETagstringWeak ETag of the current snapshot, e.g. W/"a1b2c3...". Send back as If-None-Match on the next request to revalidate.
X-Snapshot-Built-AtstringUTC timestamp (seconds, ISO 8601, no timezone suffix) of when the snapshot was last rebuilt, e.g. 2026-04-25T10:30:00.
X-Snapshot-RowsintegerNumber of rows contained in the snapshot.
Cache-Controlstringprivate, 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_namestringSteam market hash name
phasestringPhase variant (e.g. "Phase 2", "Ruby"). Empty for non-Doppler items.
min_pricedecimalLowest available price
countintegerNumber of items currently on sale for this skin
Decompressed body
{
  "data": [
    {
      "hash_name": "AK-47 | Redline (Field-Tested)",
      "phase": "",
      "min_price": "28.5000",
      "count": 12
    },
    {
      "hash_name": "★ Karambit | Doppler (Factory New)",
      "phase": "Phase 2",
      "min_price": "1523.0000",
      "count": 3
    }
  ]
}

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.

GET/market/items

Returns all available listings sorted by price (lowest first), allowing you to compare and select the exact item to buy.

Query parameters

hash_namerequiredstringSteam market hash name (exact match)
phasestringFilter by phase (e.g. "Phase 1", "Sapphire")
price_maxdecimalMaximum price filter
delivery_typestringFilter by delivery type: auto (instant) or manual. Default returns both. Manual listings only appear if your account has manual-delivery access.
pageintegerPage number (default: 1)
page_sizeintegerItems per page (default: 10, max: 100)

Response fields (per item)

idintegerInventory item ID (use for purchase)
asset_idstring | nullSteam asset ID. 64-bit number returned as a string to preserve precision (exceeds JS Number.MAX_SAFE_INTEGER); may be null if not available for this item.
hash_namestringSteam market hash name
name_zhstringChinese name
phasestringPhase variant
pricedecimalSelling price (USD, 4 decimal places)
delivery_typestringauto (instant delivery) or manual (slower, manual delivery)
float_valuedecimal | nullFloat value (up to 18 decimal places)
paint_seedinteger | nullPaint seed
paint_indexinteger | nullPaint index
name_tagstringApplied name tag
stickersarrayApplied stickers
charmarrayAttached charms (keychain slot)
Example request
GET /api/v1/market/items?hash_name=Souvenir+Galil+AR+%7C+Green+Apple+(Factory+New)&page_size=2

Example rows are illustrative; IDs and stock change over time. stickers and charm entries do not include skin_id. Attachment objects may include a display name, slot/wear fields, and optional placement offsets depending on the item.

Example response
{
  "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": [ ... ]
    }
  ]
}
POST/market/items/batch

Batch 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). Results reflect current listings.

Request body

itemsrequiredarrayArray of query objects (1–50 entries)
items[].hash_namerequiredstringSteam market hash name (exact match)
items[].phasestringOptional phase filter (e.g. "Phase 2", "Sapphire")

Optional query parameter delivery_type (auto / manual) filters all results by delivery type, same as List Items.

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, delivery_type, float_value, paint_seed, paint_index, name_tag, stickers, charm.

Example request
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"}
  ]
}
Example response
{
  "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": []
  }
}
GET/market/items/json

Returns a download URL for the full available item list (gzip-compressed NDJSON, one JSON object per line).

Special permission required — contact an administrator to apply.

Response fields

download_urlstringURL to download the file. No auth header on this request.
expires_atstringWhen download_url expires (ISO 8601). Call this endpoint again for a new URL.

File line format

Decompress gzip, then read one JSON object per line. Fields match List Items (item_id instead of id; keychains instead of charm).

item_idintegerItem ID (use for purchase)
hash_namestringSteam market hash name
pricedecimalSelling price (USD)
phasestringPhase variant
float_valuedecimal | nullFloat value
stickersarray | nullApplied stickers
keychainsarray | nullApplied charms
Example request
GET /api/v1/market/items/json
Authorization: Token sst_a1b2c3d4e5f6...
Example response
{
  "code": 1000,
  "message": "ok",
  "data": {
    "download_url": "https://cdn.example.com/items/export.ndjson.gz?token=...",
    "expires_at": "2026-05-18T00:45:00"
  }
}
Sample line (after decompress)
{"item_id":12001,"hash_name":"AK-47 | Redline (Field-Tested)","phase":"","price":"28.5000","float_value":"0.256312847137451170","stickers":[],"keychains":[]}

If the file is not ready yet, the API returns 503 with Retry-After — wait and retry.

Python example
import gzip, json, requests

API  = "https://api.tradestation.gg/api/v1"
AUTH = {"Authorization": "Token sst_a1b2c3d4e5f6..."}

r = requests.get(f"{API}/market/items/json", headers=AUTH, timeout=30)
r.raise_for_status()
url = r.json()["data"]["download_url"]

with requests.get(url, stream=True, timeout=300) as resp:
    resp.raise_for_status()
    with gzip.GzipFile(fileobj=resp.raw) as gz:
        for line in gz:
            item = json.loads(line)
            # ...

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 the order amount is reserved — 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).

POST/market/orders/buy

Purchase a specific inventory item by ID. The item will be delivered to your Steam trade URL.

Request body

item_idrequiredintegerInventory item ID (from market listing)
trade_urlrequiredstringSteam trade URL (https://steamcommunity.com/tradeoffer/new/?partner=...&token=...)
external_order_nostringYour order reference (max 64 chars, unique per user)
max_pricedecimalMax acceptable price; returns 3010 if exceeded

Buying a manual delivery item requires manual-delivery access on your account; otherwise the request returns 3011. For manual items the trade_url must also be registered in your manual-delivery whitelist, or it returns 3012. Auto items are unaffected.

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.

Example request
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",
  "max_price": "28.5000"
}
Success response (HTTP 201)
{
  "code": 1000,
  "message": "ok",
  "data": {
    "order_no": "T20260407143022849132",
    "external_order_no": "my-order-001",
    "status": "created",
    "price": "28.5000",
    "delivery_type": "auto",
    "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
  }
}
Price exceeded (HTTP 400, code 3010)
{
  "code": 3010,
  "message": "Item price exceeds the specified max_price",
  "data": null
}
POST/market/orders/quick-buy

Purchase the lowest-priced available item for a given skin. Automatically selects the cheapest item.

Request body

hash_namerequiredstringSteam market hash name
trade_urlrequiredstringSteam trade URL
phasestringLimit to a specific phase
max_pricedecimalMax acceptable price; returns 4003 if no match
delivery_typestringNarrow selection: auto / manual / all (default all). Manual is only selected if your account has manual-delivery access; selecting a manual item also requires a whitelisted trade_url.
external_order_nostringYour order reference (max 64 chars)
Example request
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.

GET/market/orders

Lists 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

statusstringFilter by order status: created pending completed failed cancelled reversed
external_order_nostringFilter by your order reference. Comma-separated, up to 50. Multi-value queries include a not_found array for missing refs.
start_datestringStart date inclusive (ISO 8601 format: YYYY-MM-DD)
end_datestringEnd date inclusive (ISO 8601 format: YYYY-MM-DD)
pageintegerPage number (default: 1)
page_sizeintegerItems 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_nostringTradeStation order number
external_order_nostringYour external reference
statusstringOrder status
pricedecimalTransaction price
steam_offer_idstringSteam 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_namestringSkin market hash name
name_zhstringChinese name
phasestringPhase variant
float_valuedecimal | nullItem float (this instance)
paint_seedinteger | nullItem paint seed
paint_indexinteger | nullItem paint index
name_tagstringApplied name tag on the item
stickersarrayApplied stickers (same format as market listings)
charmarrayCharms / keychain slot JSON
fail_codeinteger | nullFailure code (5xxx) if applicable
fail_reason_displaystringHuman-readable failure reason
created_atdatetimeISO 8601 timestamp
completed_atdatetime | nullCompletion time
reversible_untildatetime | nullReverse window cutoff (UTC). null if not completed.
is_reversiblebooleanWhether the order is currently within the reverse window.
Example request
GET /api/v1/market/orders?status=completed&page=1&page_size=10
Example response
{
  "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",
      "delivery_type": "auto",
      "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
    }
  ]
}
Example request (batch by external_order_no)
GET /api/v1/market/orders?external_order_no=inv-001,inv-002,inv-404&page_size=50
Example response (batch by external_order_no)
{
  "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"]
}
GET/market/orders/{order_no}

Retrieve a single order. Response body matches one element from GET /market/orders (same fields and nesting).

Path parameters

order_norequiredstringOrder number or your external_order_no

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), and delivery_type (auto / manual).

For orders in terminal states (failed, cancelled, reversed), the top-level code will be the fail_code (5xxx) instead of 1000.

Example request (by order_no)
GET /api/v1/market/orders/T20260415120000123456
Example request (by external_order_no)
GET /api/v1/market/orders/inv-2026-0415-001
Example response (active / success)
{
  "code": 1000,
  "message": "ok",
  "data": {
    "order_no": "T20260415120000123456",
    "external_order_no": "inv-2026-0415-001",
    "status": "completed",
    "price": "28.5000",
    "delivery_type": "auto",
    "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.

Example response (terminal: failed / cancelled / reversed)
{
  "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
  }
}
GET/wallet

Returns your current wallet balance.

Response fields

currencystringWallet currency (always USD)
availabledecimalAvailable balance — can be used for trading and withdrawal
helddecimalBalance included in tradable total but not yet withdrawable
frozendecimalBalance reserved for active orders
totaldecimalTotal balance (available + held + frozen)
tradabledecimalTradable balance (available + held)
withdrawabledecimalWithdrawable balance (available only)
statusstringWallet status: active or frozen
updated_atdatetimeLast balance update time (ISO 8601)
Example response
{
  "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"
  }
}
GET/wallet/transactions

Lists your wallet transactions in reverse chronological order. Supports filtering by type and date range.

Query parameters

tx_typestringFilter by transaction type: deposit withdraw trade_freeze trade_unfreeze trade_pay trade_income adjustment transfer_in transfer_out etc.
start_datestringStart date inclusive (ISO 8601 format: YYYY-MM-DD)
end_datestringEnd date inclusive (ISO 8601 format: YYYY-MM-DD)
pageintegerPage number (default: 1)
page_sizeintegerItems 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_nostringTransaction reference number
tx_typestringTransaction type
amountdecimalChange amount (positive = credit, negative = debit)
balance_beforedecimalAvailable balance before this transaction
held_beforedecimalHeld balance before this transaction
frozen_beforedecimalFrozen balance before this transaction
balance_afterdecimalAvailable balance after this transaction
held_afterdecimalHeld balance after this transaction
frozen_afterdecimalFrozen balance after this transaction
biz_typestringBusiness type (e.g. trade_freeze, adjustment)
biz_idstringRelated business reference (e.g. order number)
created_atdatetimeTransaction time (ISO 8601)
Example request
GET /api/v1/wallet/transactions?start_date=2026-04-01&end_date=2026-04-14&page_size=2
Example response
{
  "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",
      "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",
      "created_at": "2026-04-14T15:43:17.378123Z"
    }
  ]
}