> ## 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 trade URL

> Покупайте до 100 предметов и доставляйте их прямо на любой указанный вами Steam trade URL, оплачивая из подтверждённого баланса. Создано для оптовых покупок и автоматической доставки.

Этот эндпоинт позволяет покупать и доставлять предметы напрямую на **любой** указанный вами Steam trade URL — не только на trade URL, привязанный к вашему аккаунту. Trade URL формируется из полей `partner` и `token`. Покупки финансируются **только** из вашего **подтверждённого** (защищённого от реверса) баланса, что делает эндпоинт пригодным для оптовых объёмов и потоков автоматической доставки.

Эндпоинт **идемпотентен через поле тела `custom_id`**: повтор с тем же `custom_id` воспроизводит исходную покупку, а не делает покупку дважды, и воспроизведённый ответ содержит заголовок `Idempotent-Replayed: true`.

<Warning>
  Этот эндпоинт работает за kill-switch и требует аккаунта, для которого включена торговля и нет истории реверсов. Когда kill-switch выключен, возвращается `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>
  Значение `partner` из Steam trade URL (1–32 символа). Вместе с `token` образует конечный trade URL, на который доставляются предметы.
</ParamField>

<ParamField body="token" type="string" required>
  Значение `token` из Steam trade URL (1–32 символа). Вместе с `partner` образует конечный trade URL.
</ParamField>

<ParamField body="max_price_usd" type="number">
  Верхняя граница итоговой цены в USD. Если живой итог превышает её, заказ отклоняется с ошибкой `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>
      Steam ID, определённый по переданным `partner` + `token`.
    </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`             | Один или несколько предметов нельзя доставить через этот эндпоинт (например, id `ss_live_*`).    |
| 400         | `invalid_trade_url`            | `partner` + `token` не образуют валидный Steam trade URL.                                        |
| 401         | `invalid_api_key`              | Отсутствует или некорректный API-ключ.                                                           |
| 402         | `insufficient_settled_balance` | Подтверждённый баланс ниже суммы заказа. Включает `required_usd` и `settled_usd`.                |
| 402         | `insufficient_balance`         | Баланс ниже суммы заказа.                                                                        |
| 403         | `external_buy_disabled`        | Kill-switch выключен; эндпоинт сейчас недоступен.                                                |
| 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>
  Средства берутся исключительно из вашего **подтверждённого** баланса. Перед большой партией проверяйте `settled_balance_usd` через [`GET /v1/balance`](/api-reference/get-balance) и всегда передавайте `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.

````