> ## Documentation Index
> Fetch the complete documentation index at: https://assetpay.gg/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Withdrawal

> Start a quick withdrawal: pass an itemId, a per-unit price ceiling and an amount, and AssetPay buys the cheapest listings at or below it. CS2 and Rust.

Initiates a **quick** withdrawal. Instead of naming specific listings, you pass an `itemId`, a per-unit price ceiling, and an amount — AssetPay buys the cheapest available listings at or below your ceiling and delivers them to the user via Steam trade offer.

**Available for CS2 and Rust.** Other games are rejected with `QUICK_BUY_UNSUPPORTED_GAME` (32). For Rust, `phase` and `delivery: "instant"` are not available (CS2-only options).

**Authentication:** Client Token (`Authorization` header)

## Request

```http theme={null}
POST https://api.assetpay.gg/client/trading/withdraw/quick
Content-Type: application/json
Authorization: CLIENT_TOKEN

{
  "itemId": "dc3c4460d814ac35",
  "maxPrice": 67.39,
  "amount": 3,
  "delivery": "instant",
  "externalId": "qb_unique_789"
}
```

### Body Parameters

| Parameter        | Type   | Required | Description                                                                                                                                                                                                                                                                                                                        |
| ---------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `itemId`         | string | Yes\*    | Item id from `/secure/prices` (CS2 catalog id, or any listing id of the item for Rust). 5–256 chars. Provide this **or** `marketHashName`; `itemId` wins when both are sent.                                                                                                                                                       |
| `marketHashName` | string | Yes\*    | Exact market hash name (e.g. `AK-47 \| Redline (Field-Tested)`), resolved to the item. Ignored when `itemId` is supplied.                                                                                                                                                                                                          |
| `maxPrice`       | number | Yes      | **Gross** per-unit price ceiling in USD (fee-inclusive — the same basis as the `withdraw` price in `/secure/prices`). Max \$100,000. AssetPay backs its fee out of this to get the sourcing ceiling sent to the marketplace.                                                                                                       |
| `amount`         | number | Yes      | How many units to buy. Integer, 1–200.                                                                                                                                                                                                                                                                                             |
| `externalIds`    | array  | No       | One reference of your own per requested unit (each 1–128 chars), applied to the pre-filled rows in order. Must hold **exactly** `amount` entries. Accepted in place of the item id by both [cancel](/docs/api-reference/trading/cancel-withdraw-item) endpoints.                                                                        |
| `delivery`       | string | No       | `"standard"` or `"instant"`. Defaults to `"standard"`. `"instant"` is CS2-only.                                                                                                                                                                                                                                                    |
| `phase`          | string | No       | **CS2 only.** Doppler phase to buy: `"Phase 1"`–`"Phase 4"`, `"Ruby"`, `"Sapphire"`, `"Black Pearl"`, `"Emerald"`. Prices against that phase's floor for the requested delivery mode. Combines with `delivery: "instant"`, though many phases have no instant listing — check `phases[].withdraw.instant` on /secure/prices first. |
| `game`           | string | No       | `"730"` (CS2) or `"252490"` (Rust). Defaults to `"730"`.                                                                                                                                                                                                                                                                           |
| `autoCancel`     | number | No       | **CS2 only.** Minutes after creation to automatically cancel any unit still undelivered. Integer, 30-720. Defaults to `30`; send `720` to disable. Rejected on Rust with `VALIDATION_FAILED`. See [Automatic cancellation](/docs/guides/withdrawals#automatic-cancellation).                                                            |
| `externalId`     | string | No       | Your unique tracking ID (max 128 chars). Must be unique per trade.                                                                                                                                                                                                                                                                 |

\* Provide either `itemId` or `marketHashName`.

## Response

```json theme={null}
{
  "requestId": "...",
  "success": true,
  "data": {
    "id": "trade-uuid",
    "type": "withdraw",
    "source": "client",
    "status": "initiated",
    "game": "730",
    "externalId": "qb_unique_789",
    "merchantId": "merchant-uuid",
    "clientUserId": "client-uuid",
    "clientSteamID": "76561198012345678",
    "clientTradeUrl": "https://steamcommunity.com/tradeoffer/new/?partner=...",
    "items": [
      { "id": "dc3c4460d814ac35", "appid": 730, "tradable": true, "amount": 1, "status": "initiated", "offer": { "price": 67.39, "delivery": "instant" } },
      { "id": "dc3c4460d814ac35", "appid": 730, "tradable": true, "amount": 1, "status": "initiated", "offer": { "price": 67.39, "delivery": "instant" } },
      { "id": "dc3c4460d814ac35", "appid": 730, "tradable": true, "amount": 1, "status": "initiated", "offer": { "price": 67.39, "delivery": "instant" } }
    ],
    "totalPrice": 202.17,
    "createdAt": "2026-05-31T10:00:00.000Z",
    "updatedAt": "2026-05-31T10:00:00.000Z"
  }
}
```

The response is a full [Trade](/docs/reference/types#trade) object. Unlike the deterministic [`/client/trading/withdraw`](/docs/api-reference/trading/withdraw), the actual filled listings are **not known yet** at creation, so:

* `items` contains **one pre-filled row per requested unit** (so `amount: 3` returns 3 rows), each carrying the ceiling `price` and `delivery` — the same minimal shape as a standard buy item. The catalog `itemId` is used as each row's placeholder `id` until it is **bound** to a real listing.
* `totalPrice` is the **worst-case lock** (`amount × maxPrice`, after rounding), not the final spend.

As the order fills, each row is bound to a real listing — its `id` becomes the listing id and its price updates to the actual fill — and the trade settles asynchronously. For CS2 the fills arrive from the marketplace over time; for Rust the cheapest units at or below your ceiling are selected in one pass right after approval. Fills may be **fewer than requested** if supply runs out at your ceiling; those unfilled rows go to `failed`, and the unfilled units plus any below-ceiling savings are refunded. Poll `GET /client/trades/{id}` or rely on callbacks / the WebSocket feed for the final view. Once settled, `totalPrice` reflects the **actual** amount spent on the filled items.

## How it works

1. **Lock** — the worst-case total (`amount × maxPrice`) is locked from your merchant balance up front.
2. **Approval** — an `initiated` callback fires to your backend before anything is purchased (same as the standard withdraw). Approve with `2xx`, reject with `4xx`.
3. **Fill** — AssetPay buys the cheapest `amount` listings at or below the sourcing ceiling. Partial fills are normal.
4. **Settle** — filled items settle (sourcing + your fee); the unfilled remainder and below-ceiling savings are refunded to your balance.

<Warning>
  Quick withdrawals require your merchant account to have an active callback URL configured. Calling this endpoint without one immediately fails with `MERCHANT_NO_CALLBACK_URL` (1705).
</Warning>

## Rate Limits

| Merchant Status | Limit              |
| --------------- | ------------------ |
| Verified        | 500 requests / min |
| Unverified      | 5 requests / min   |

Shared across all clients of the same merchant.

## Errors

| Code | Key                          | When                                                                                                      |
| ---- | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| 1    | `EXTERNAL_ID_EXISTS`         | The `externalId` is already in use                                                                        |
| 32   | `QUICK_BUY_UNSUPPORTED_GAME` | `game` is not CS2 (`"730"`) or Rust (`"252490"`)                                                          |
| 12   | `MERCHANT_BALANCE_LOW`       | Your merchant balance can't cover the worst-case lock                                                     |
| 13   | `INVALID_TRADEURL`           | User's trade URL is invalid                                                                               |
| 14   | `LISTING_NOT_FOUND`          | Rust: the `itemId` / `marketHashName` doesn't match any current listing                                   |
| 20   | `WITHDRAW_IN_PROGRESS`       | Another withdrawal is already processing for this user                                                    |
| 42   | `INSUFFICIENT_STOCK`         | Rust: no units currently sourceable at or below `maxPrice`                                                |
| 1001 | `VALIDATION_FAILED`          | `amount` out of range (1–200), `maxPrice` ≤ 0, `phase` / instant delivery on Rust, or other invalid input |
| 1601 | `INVALID_AMOUNT`             | The derived sourcing ceiling or lock total was zero or negative                                           |
| 1705 | `MERCHANT_NO_CALLBACK_URL`   | Merchant has no active callback URL configured                                                            |
