Skip to main content
Initiates a withdrawal (buy) trade. AssetPay purchases the item from a marketplace supplier and delivers it to the user via Steam trade offer. Authentication: Client Token (Authorization header)

Request

Body Parameters

Response

The response is a full Trade object. Each withdrawal item carries its own status field that mirrors the trade-level status as it progresses. On a freshly initiated withdraw the items only carry the data you submitted (itemId, offer.price); Steam-side fields like name, marketHashName, type, and iconUrl are omitted until AssetPay has fetched them from the marketplace. They populate on subsequent state changes; poll GET /client/trades/{id} or rely on callbacks for the resolved per-item view.

Price validation

Where AssetPay prices an item at creation, it compares the current price against the price you sent:
  • Lower or equal: accepted, and the item is charged at the current price.
  • Higher: rejected with PRICE_CHANGED, unless it still fits the item’s maxPrice or, when maxPrice is absent, price plus slippageBps. Every item that failed is named in details.items[] as { itemId, quoted, current }, so you can requote just those and retry.
This check applies to Rust items and to CS2 items served from AssetPay’s own stock. Other CS2 items are bought from the marketplace after approval and are not re-priced at creation: price is locked and is the ceiling for that purchase, and maxPrice / slippageBps do not apply. A cheaper fill is refunded on completion (see price true-up). A listing already known to be gone is rejected at creation with LISTING_NOT_FOUND; one that disappears or rises above the ceiling after that fails the item rather than the request. A single trade cannot mix CS2 items from AssetPay’s own stock with marketplace items (MIXED_SUPPLIER_TRADE).

How Balance Approval Works

After this endpoint is called, AssetPay sends an initiated callback to your backend before purchasing anything. Your backend checks the user’s balance, deducts it, and responds with 2xx to approve. If the balance is insufficient, respond with 4xx (e.g. 402 Payment Required) to reject the trade. See the Withdrawals guide for details.
Withdrawals require your merchant account to have an active callback URL and an API secret configured. Calling this endpoint without them fails immediately and no trade is created: MERCHANT_NO_CALLBACK_URL (1705) with no callback URL, MERCHANT_CALLBACK_URL_DISABLED (1706) when the URL was auto-disabled after repeated delivery failures (re-save it to re-enable), or MERCHANT_NO_API_SECRET (1707) with no API secret.

Rate Limits

Shared across all clients of the same merchant.

Errors