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

# POST /v1/market/buy — 购买并交付到 Steam 交易链接

> 一次最多购买 100 件商品，并直接交付到您提供的任意 Steam 交易链接，使用已结算余额支付。专为批发与自动化交付而设计。

此端点允许您将商品购买并直接交付到您提供的**任意** Steam 交易链接——而不仅限于绑定到您账户的交易链接。交易链接由 `partner` 和 `token` 字段组成。购买**只能**使用您的**已结算**（不可撤销）余额，因此适用于批发量与自动化交付工作流。

该端点**通过 `custom_id` 请求体字段实现幂等性**：使用相同的 `custom_id` 重试会重放原始的购买，而不会再次扣款；重放的响应会携带 `Idempotent-Replayed: true` 响应头。

<Warning>
  此端点处于熔断开关保护之下，要求账户启用了交易且不可撤销状态干净。熔断开关关闭时，将返回 `403 external_buy_disabled`。
</Warning>

**需要身份验证。** 请将密钥作为 `Authorization: Bearer csb_pub_...` 发送。

**需要交易能力。** 该密钥必须启用购买功能，且账户必须处于不可撤销状态干净。

## 请求体

<ParamField body="item_ids" type="string[]" required>
  1–100 个唯一的挂单 id。
</ParamField>

<ParamField body="partner" type="string" required>
  Steam 交易链接中的 `partner` 值（1–32 个字符）。与 `token` 一起构成商品交付的目标交易链接。
</ParamField>

<ParamField body="token" type="string" required>
  Steam 交易链接中的 `token` 值（1–32 个字符）。与 `partner` 一起构成目标交易链接。
</ParamField>

<ParamField body="max_price_usd" type="number">
  美元价格上限。如果实时总价超过该值，订单将以 `price_moved` 被拒绝且不扣款。强烈建议使用。
</ParamField>

<ParamField body="custom_id" type="string">
  幂等键（1–128 个字符）。使用相同 `custom_id` 重试会重放原始购买；重放响应会携带 `Idempotent-Replayed: true`。
</ParamField>

<ParamField body="skip_unavailable" type="boolean" default="false">
  如果为 `true`，跳过已不再可用的商品而不会让整个请求失败。
</ParamField>

## 响应字段

<ResponseField name="data" type="object" required>
  <Expandable title="data object">
    <ResponseField name="purchase_id" type="string" required />

    <ResponseField name="steam_id" type="string" required>
      由所提供的 `partner` + `token` 解析得到的 Steam ID。
    </ResponseField>

    <ResponseField name="created_at" type="datetime" required />

    <ResponseField name="custom_id" type="string | null" />

    <ResponseField name="skins" type="object[]" required>
      逐件结果。

      <Expandable title="skin object">
        <ResponseField name="name" type="string | null" />

        <ResponseField name="price" type="number | null" />

        <ResponseField name="status" type="string" />

        <ResponseField name="return_reason" type="string | null" />

        <ResponseField name="steam_trade_offer_id" type="string | null" />
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## 示例请求

```bash theme={null}
curl -X POST https://csboard.com/v1/market/buy \
  -H "Authorization: Bearer csb_pub_..." \
  -H "Content-Type: application/json" \
  -d '{
    "item_ids": ["itm_8841201", "itm_8841340"],
    "partner": "447383001",
    "token": "Ab3xZ9Qp",
    "max_price_usd": 30.00,
    "custom_id": "batch-2026-06-29-01",
    "skip_unavailable": false
  }'
```

## 示例响应

```json theme={null}
{
  "data": {
    "purchase_id": "pur_01J9Z3K8Q2",
    "steam_id": "76561198000000000",
    "created_at": "2026-06-29T17:12:04Z",
    "custom_id": "batch-2026-06-29-01",
    "skins": [
      {
        "name": "AK-47 | Redline (Minimal Wear)",
        "price": 14.37,
        "status": "delivering",
        "return_reason": null,
        "steam_trade_offer_id": "5512345678"
      }
    ]
  }
}
```

## 错误代码

| HTTP 状态码 | 代码                             | 含义                                                                |
| -------- | ------------------------------ | ----------------------------------------------------------------- |
| 400      | `invalid_request`              | 请求体格式错误（例如 `item_ids` 为空或超过 100）。                                 |
| 400      | `unsupported_item`             | 一个或多个商品无法通过此端点交付（例如 `ss_live_*` id）。                              |
| 400      | `invalid_trade_url`            | `partner` + `token` 无法组成有效的 Steam 交易链接。                           |
| 401      | `invalid_api_key`              | API 密钥缺失或无效。                                                      |
| 402      | `insufficient_settled_balance` | 已结算余额低于订单总额。返回中包含 `required_usd` 和 `settled_usd`。                 |
| 402      | `insufficient_balance`         | 余额低于订单总额。                                                         |
| 403      | `external_buy_disabled`        | 熔断开关已关闭；此端点当前已禁用。                                                 |
| 403      | `trading_not_enabled`          | 该密钥未启用购买功能。                                                       |
| 403      | `account_restricted`           | 此端点要求账户处于不可撤销状态干净。                                                |
| 409      | `item_unavailable`             | 一个或多个商品已不再可用。返回中包含 `unavailable_ids[]`。                           |
| 409      | `price_moved`                  | 实时总价超过上限。返回中包含 `quoted_max_usd`、`current_total_usd` 以及 `items[]`。 |
| 409      | `idempotency_in_progress`      | 具有该 `custom_id` 的请求仍在处理中。                                         |
| 409      | `price_updating`               | 价格正在刷新；请稍后重试。                                                     |
| 429      | `rate_limit_exceeded`          | 请求过多。请按照 `Retry-After` 响应头中的秒数退避。                                 |
| 500      | `order_failed`                 | 购买无法完成。                                                           |

<Note>
  资金完全来自您的**已结算**余额。在大批量下单前，请检查 [`GET /v1/balance`](/api-reference/get-balance) 上的 `settled_balance_usd`，并始终发送 `max_price_usd` 作为超额扣款保护。
</Note>


## OpenAPI

````yaml POST /market/buy
openapi: 3.1.0
info:
  title: CSBoard API
  version: 1.0.0
  description: >-
    Market data over the CSBoard marketplace — live listings, floats, stickers,
    minAsk prices, FX rates — plus opt-in buying straight from your balance.
    Free to read, key-gated, built for automation.
  contact:
    name: CSBoard
    url: https://csboard.com/docs
servers:
  - url: https://csboard.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Status
    description: Liveness and freshness probes.
  - name: Market data
    description: Read the live catalog, prices, and FX rates.
  - name: Trading
    description: Buy listings from your CSBoard balance. Opt-in, key-gated.
  - name: Account
    description: Your balance, settled funds, and trading status.
paths:
  /market/buy:
    post:
      tags:
        - Trading
      summary: Buy and deliver to a Steam trade URL
      description: >-
        Buy up to 100 items and deliver them straight to any Steam trade URL you
        supply (built from `partner` + `token`), paid from your **settled**
        (reversal-safe) balance. Built for wholesale and automated delivery.
        Idempotent via the `custom_id` body field — a retry with the same
        `custom_id` replays the original purchase and the response carries the
        `Idempotent-Replayed: true` header. This endpoint ships behind a
        kill-switch and requires a trading-enabled, reversal-clean account.
      operationId: marketBuy
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalBuyRequest'
            example:
              item_ids:
                - itm_8841201
                - itm_8841340
              partner: '447383001'
              token: Ab3xZ9Qp
              max_price_usd: 30
              custom_id: batch-2026-06-29-01
              skip_unavailable: false
      responses:
        '201':
          description: Purchase accepted and debited from settled balance.
          headers:
            Idempotent-Replayed:
              description: >-
                Present and `true` when this response replays an earlier
                purchase made with the same `custom_id`.
              schema:
                type: boolean
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalBuyResult'
              example:
                data:
                  purchase_id: pur_01J9Z3K8Q2
                  steam_id: '76561198000000000'
                  created_at: '2026-06-29T17:12:04Z'
                  custom_id: batch-2026-06-29-01
                  skins:
                    - name: AK-47 | Redline (Minimal Wear)
                      price: 14.37
                      status: delivering
                      return_reason: null
                      steam_trade_offer_id: '5512345678'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_request:
                  summary: Malformed body
                  value:
                    code: invalid_request
                    detail: item_ids must contain 1–100 unique ids.
                unsupported_item:
                  summary: Item cannot be delivered this way
                  value:
                    code: unsupported_item
                    detail: One or more items cannot be delivered via this endpoint.
                invalid_trade_url:
                  summary: Bad partner/token
                  value:
                    code: invalid_trade_url
                    detail: partner and token do not form a valid Steam trade URL.
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: invalid_api_key
                detail: Missing or invalid API key.
        '402':
          description: Not enough funds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                insufficient_settled_balance:
                  summary: Settled balance too low
                  value:
                    code: insufficient_settled_balance
                    detail: Settled balance is below the order total.
                    required_usd: 26.47
                    settled_usd: 10
                insufficient_balance:
                  summary: Balance too low
                  value:
                    code: insufficient_balance
                    detail: Balance is below the order total.
        '403':
          description: Not permitted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                external_buy_disabled:
                  summary: Kill-switch off
                  value:
                    code: external_buy_disabled
                    detail: This endpoint is currently disabled.
                trading_not_enabled:
                  summary: Buying off for key
                  value:
                    code: trading_not_enabled
                    detail: Enable buying for this key in your profile.
                account_restricted:
                  summary: Account not eligible
                  value:
                    code: account_restricted
                    detail: This endpoint requires a reversal-clean account.
        '409':
          description: Conflict.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                item_unavailable:
                  summary: Item sold out
                  value:
                    code: item_unavailable
                    detail: One or more items are no longer available.
                    unavailable_ids:
                      - itm_8841999
                price_moved:
                  summary: Live price exceeded ceiling
                  value:
                    code: price_moved
                    detail: Live total exceeds max_price_usd.
                    quoted_max_usd: 30
                    current_total_usd: 31.2
                    items:
                      - id: itm_8841201
                        market_hash_name: AK-47 | Redline (Minimal Wear)
                        price_usd: 15.1
                idempotency_in_progress:
                  summary: Earlier request still running
                  value:
                    code: idempotency_in_progress
                    detail: A request with this custom_id is still being processed.
                price_updating:
                  summary: Prices refreshing
                  value:
                    code: price_updating
                    detail: Prices are updating; retry shortly.
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          description: The purchase could not be completed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: order_failed
                detail: The purchase could not be completed.
components:
  schemas:
    ExternalBuyRequest:
      type: object
      properties:
        item_ids:
          type: array
          items:
            type: string
          minItems: 1
          maxItems: 100
          uniqueItems: true
          description: 1–100 unique listing ids to buy.
        partner:
          type: string
          minLength: 1
          maxLength: 32
          description: >-
            Steam trade URL `partner` value. With `token`, forms the destination
            trade URL.
        token:
          type: string
          minLength: 1
          maxLength: 32
          description: >-
            Steam trade URL `token` value. With `partner`, forms the destination
            trade URL.
        max_price_usd:
          type: number
          description: >-
            Total ceiling in USD. Order is rejected with `price_moved` if the
            live total exceeds it.
        custom_id:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Idempotency key. A retry with the same value replays the original
            purchase.
        skip_unavailable:
          type: boolean
          default: false
          description: >-
            If true, skip items that are no longer available instead of failing
            the whole request.
      required:
        - item_ids
        - partner
        - token
    ExternalBuyResult:
      type: object
      properties:
        data:
          type: object
          properties:
            purchase_id:
              type: string
            steam_id:
              type: string
            created_at:
              type: string
              format: date-time
            custom_id:
              type:
                - string
                - 'null'
            skins:
              type: array
              items:
                type: object
                properties:
                  name:
                    type:
                      - string
                      - 'null'
                  price:
                    type:
                      - number
                      - 'null'
                  status:
                    type: string
                  return_reason:
                    type:
                      - string
                      - 'null'
                  steam_trade_offer_id:
                    type:
                      - string
                      - 'null'
          required:
            - purchase_id
            - steam_id
            - created_at
            - skins
      required:
        - data
    Error:
      type: object
      description: >-
        All errors return { code, detail }. Some carry extra fields (e.g.
        price_moved adds current_total_usd, insufficient_balance adds
        required_usd/current_usd).
      properties:
        code:
          type: string
          description: >-
            Machine-readable error code, e.g. rate_limit_exceeded,
            trading_not_enabled, price_moved.
        detail:
          type: string
          description: Human-readable explanation.
      required:
        - code
  responses:
    RateLimited:
      description: Rate limit exceeded. Includes a Retry-After header.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: rate_limit_exceeded
            message: Too many requests.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Send your key as a Bearer token on every request: `Authorization: Bearer
        csb_pub_...`. Generate keys in your CSBoard profile.

````