> ## 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/p2p/listings — List Your CS2 Items on the P2P Market

> Put one CS2 item, or up to 50, up for sale on the CSBoard P2P market at your own price. Free with any API key; Idempotency-Key required.

Publishes your own CS2 items on the CSBoard P2P market at your price. Send one item, or a batch of up to 50 as `{ "items": [...] }`. Take `operational_asset_id` and `asset_revision` from [`GET /v1/p2p/inventory`](/api-reference/get-p2p-inventory) and send them unchanged.

**Authentication required.** Send your key as `Authorization: Bearer csb_pub_...`. Free — any valid key, no balance requirement and no trading permission.

## Seller rules

The same rules as on the website apply:

* a verified email or a linked Telegram, so we can tell you when an item sells;
* the CSBoard extension or app able to send the Steam trade, and Steam Mobile Authenticator on the account;
* no P2P cooldown, suspension or shop lock;
* a current read of your inventory (see `inventory_proof` in [`GET /v1/p2p/inventory`](/api-reference/get-p2p-inventory)).

## Price floor

The price may not be under **half of our market price** for the item. On the website a seller can confirm a lower price after a warning. Over an API key there is no such confirmation: a lower price answers `422 price_below_market` with `market_usd` and `floor_usd`, so you can adjust and resend. This refusal does not spend your `Idempotency-Key`. When we have no market price for an item, no floor applies.

Prices are in USD, from `0.10` to `100000`, in whole cents. `12.345` is refused, not rounded.

## Idempotency

`Idempotency-Key` is **required** (8–128 characters, unique per publish request). If you resend the same request with the same key, every item that was already published comes back as it is instead of being listed twice. A single replayed item answers `200` with the header `Idempotent-Replay: true`.

* Reusing a key with a different price or revision answers `409 idempotency_key_mismatch`.
* After `409 idempotency_key_consumed`, an earlier attempt failed part-way — retry with a new key.

## Responses

* **One item:** `201` with the listing, or `200` on a replay.
* **A batch:** always `200`, with one result per item in `data`. One item that fails does not stop the others; a failed item carries the `status` and `code` it would have answered on its own.

Writes are limited to **30 requests per minute per key**, shared with price changes and removals.

## Example request

```bash theme={null}
curl -X POST https://csboard.com/v1/p2p/listings \
  -H "Authorization: Bearer csb_pub_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0b7d4c1e-6f2a-4b9e-8c3d-5a1f2e9b7c40" \
  -d '{
    "items": [
      {
        "operational_asset_id": "5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30",
        "asset_revision": "sha256:fd0e6de607b774aaaf4d9cdb7e014c003ba614b03f0460b01e8c94bce034bac5",
        "price_usd": 12.34
      },
      {
        "operational_asset_id": "c81e2d44-9b07-4f1a-b3d5-6e2a90f4c7b8",
        "asset_revision": "sha256:a5b10a9006f6ebb68f8b9e81c85b5a6d1bf0f32737fc3f57a597dd01e66e0523",
        "price_usd": 3.5
      }
    ]
  }'
```

## Example response

```json theme={null}
{
  "data": [
    {
      "operational_asset_id": "5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30",
      "success": true,
      "replay": false,
      "listing": {
        "id": "cm1xq8z4k0003ab12cd34ef56",
        "status": "active",
        "price_usd": 12.34,
        "currency": "USD",
        "commission_usd": 0.25,
        "seller_payout_usd": 12.09,
        "market_hash_name": "AK-47 | Redline (Field-Tested)",
        "item_name": "AK-47 | Redline (Field-Tested)",
        "asset_id": "38451927734",
        "operational_asset_id": "5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30",
        "float_value": 0.2711,
        "needs_resync": false,
        "created_at": "2026-10-02T12:04:11.000Z",
        "updated_at": "2026-10-02T12:04:11.000Z"
      }
    },
    {
      "operational_asset_id": "c81e2d44-9b07-4f1a-b3d5-6e2a90f4c7b8",
      "success": false,
      "status": 409,
      "code": "hold_not_ended",
      "detail": "The Steam trade hold has not ended yet."
    }
  ],
  "success_count": 1,
  "total_requested": 2
}
```

## Error codes

| HTTP status | Code | Meaning |
| - | - | - |
| 400 | `idempotency_key_required` | No `Idempotency-Key` header, or it is not 8–128 characters. |
| 400 | `invalid_request` | Malformed body — a missing field, an unknown field, or a price outside `0.10`–`100000` or with more than two decimals. |
| 400 | `no_capable_client` | Nothing on your side can send the trade. Run the CSBoard extension or app. |
| 403 | `contact_required` | Add a verified email or link Telegram first. |
| 403 | `shop_locked`, `p2p_cooldown`, `p2p_suspended`, `trading_banned` | Selling on P2P is locked for this account. Where the lock expires, the body says when. |
| 403 | `account_banned` / `ip_not_allowed` | The account is banned, or the request came from outside the key's IP allowlist. |
| 404 | `operational_asset_not_found` | The `operational_asset_id` is not in your synced inventory. |
| 409 | `asset_revision_changed` | The item changed since you read it. Read the inventory again. |
| 409 | `snapshot_stale` and other `reasons` codes | The item is not listable — the code is the first of its `reasons`. `snapshot_stale` carries `inventory_proof` to poll. |
| 409 | `already_listed` | The item already has a listing. |
| 409 | `idempotency_in_progress` | A request with this key is still running. Wait and resend the same request. |
| 409 | `idempotency_key_mismatch` / `idempotency_key_consumed` | The key was used with different details, or an earlier attempt failed. Use a new key. |
| 422 | `price_below_market` | The price is under half of our market price. See `market_usd` and `floor_usd`. |
| 429 | `rate_limit_exceeded` | Over 30 P2P writes this minute, or over your key's general limit. Wait for the `Retry-After` header value. |
| 503 | `p2p_disabled` | The P2P market is switched off right now. |

See the [P2P listing guide](/guides/p2p-listing) for what happens after an item sells.


## OpenAPI

````yaml POST /p2p/listings
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: P2P
    description: >-
      List your own CS2 skins on the CSBoard P2P market. Free — any valid key,
      no balance requirement.
  - name: Account
    description: Your balance, settled funds, and trading status.
  - name: Webhooks
    description: Register an endpoint and receive signed order updates instead of polling.
paths:
  /p2p/listings:
    post:
      tags:
        - P2P
      summary: List items on the P2P market
      description: >-
        Publish one item, or up to 50 as `{ "items": [...] }`. Free — any valid
        key, no balance requirement. CS2 only.


        The website's seller rules apply: a verified email or linked Telegram,
        the CSBoard extension or app able to send the trade, Steam Mobile
        Authenticator, no cooldown or shop lock, and a current read of your
        inventory. The price may not be under half of our market price for the
        item; unlike the website there is no way to confirm a lower one over a
        key.


        A single item answers `201` (or `200` with `Idempotent-Replay: true`
        when it was already published under this key). A batch always answers
        `200` with a result per item — one item that fails does not stop the
        others. Counts toward the 30 requests/minute P2P write limit of the key.
      operationId: createP2PListings
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          description: >-
            Required, 8–128 characters, unique per publish request. Resending
            the same request with the same key returns each item that was
            already published instead of listing it twice. A key reused with a
            different price or revision answers `409 idempotency_key_mismatch`;
            after `409 idempotency_key_consumed`, use a new key. A `422
            price_below_market` refusal does not spend the key.
          schema:
            type: string
            minLength: 8
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/P2PListingRequest'
                - type: object
                  required:
                    - items
                  additionalProperties: false
                  properties:
                    items:
                      type: array
                      minItems: 1
                      maxItems: 50
                      description: Each `operational_asset_id` may appear once.
                      items:
                        $ref: '#/components/schemas/P2PListingRequest'
            examples:
              single:
                summary: One item
                value:
                  operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
                  asset_revision: >-
                    sha256:fd0e6de607b774aaaf4d9cdb7e014c003ba614b03f0460b01e8c94bce034bac5
                  price_usd: 12.34
              batch:
                summary: Several items
                value:
                  items:
                    - operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
                      asset_revision: >-
                        sha256:fd0e6de607b774aaaf4d9cdb7e014c003ba614b03f0460b01e8c94bce034bac5
                      price_usd: 12.34
                    - operational_asset_id: c81e2d44-9b07-4f1a-b3d5-6e2a90f4c7b8
                      asset_revision: >-
                        sha256:a5b10a9006f6ebb68f8b9e81c85b5a6d1bf0f32737fc3f57a597dd01e66e0523
                      price_usd: 3.5
      responses:
        '200':
          description: >-
            A batch result, or a single item that was already published under
            this Idempotency-Key (header `Idempotent-Replay: true`).
          headers:
            Idempotent-Replay:
              description: '`true` on a replayed single-item publish.'
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/P2PBatchResult'
                  - $ref: '#/components/schemas/P2PListing'
              example:
                data:
                  - operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
                    success: true
                    replay: false
                    listing:
                      id: cm1xq8z4k0003ab12cd34ef56
                      status: active
                      price_usd: 12.34
                      currency: USD
                      commission_usd: 0.25
                      seller_payout_usd: 12.09
                      market_hash_name: AK-47 | Redline (Field-Tested)
                      item_name: AK-47 | Redline (Field-Tested)
                      asset_id: '38451927734'
                      operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
                      float_value: 0.2711
                      needs_resync: false
                      created_at: '2026-10-02T12:04:11.000Z'
                      updated_at: '2026-10-02T12:04:11.000Z'
                  - operational_asset_id: c81e2d44-9b07-4f1a-b3d5-6e2a90f4c7b8
                    success: false
                    status: 409
                    code: hold_not_ended
                    detail: The Steam trade hold has not ended yet.
                success_count: 1
                total_requested: 2
        '201':
          description: Single item published.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/P2PListing'
              example:
                id: cm1xq8z4k0003ab12cd34ef56
                status: active
                price_usd: 12.34
                currency: USD
                commission_usd: 0.25
                seller_payout_usd: 12.09
                market_hash_name: AK-47 | Redline (Field-Tested)
                item_name: AK-47 | Redline (Field-Tested)
                asset_id: '38451927734'
                operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
                float_value: 0.2711
                needs_resync: false
                created_at: '2026-10-02T12:04:11.000Z'
                updated_at: '2026-10-02T12:04:11.000Z'
        '400':
          description: >-
            Missing Idempotency-Key, a malformed body, or a seller requirement
            that is not met.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                idempotency_key_required:
                  summary: No Idempotency-Key header
                  value:
                    code: idempotency_key_required
                    detail: >-
                      Send an Idempotency-Key header (8-128 characters), unique
                      per publish request.
                invalid_request:
                  summary: Malformed body
                  value:
                    code: invalid_request
                    detail: >-
                      price_usd must be 0.10 to 100000 USD with at most two
                      decimals
                no_capable_client:
                  summary: Nothing running that can send the trade
                  value:
                    code: no_capable_client
                    detail: >-
                      Seller has no client able to deliver this item — try again
                      later.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            Forbidden — a seller rule (`contact_required`, `shop_locked`,
            `p2p_cooldown`, `p2p_suspended`, `trading_banned`), an account ban,
            or the key's IP allowlist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                contact_required:
                  summary: No verified email or Telegram to tell you about a sale
                  value:
                    code: contact_required
                    detail: >-
                      Add a verified email or link Telegram so we can tell you
                      when your item sells
                shop_locked:
                  summary: Shop locked for unanswered sales
                  value:
                    code: shop_locked
                    detail: Your shop is locked for unanswered sales
                    locked_until: '2026-10-03T09:00:00.000Z'
                p2p_cooldown:
                  summary: P2P cooldown
                  value:
                    code: p2p_cooldown
                    detail: P2P trading is on cooldown for your account
                    cooldown_until: '2026-10-02T18:00:00.000Z'
                account_banned:
                  summary: Account banned
                  value:
                    code: account_banned
                    detail: This account is banned.
                ip_not_allowed:
                  summary: Request from outside the key's IP allowlist
                  value:
                    code: ip_not_allowed
                    detail: >-
                      This API key is restricted to an IP allowlist and
                      203.0.113.7 is not on it. Update it at
                      https://csboard.com/profile?tab=api
        '404':
          description: The `operational_asset_id` is not in your synced inventory.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                operational_asset_not_found:
                  summary: Unknown asset
                  value:
                    code: operational_asset_not_found
                    detail: Asset not found in your synced inventory.
        '409':
          description: >-
            The item cannot be listed as sent, or the Idempotency-Key conflicts.
            An item that is not listable answers with the first of its `reasons`
            codes from `GET /p2p/inventory`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                asset_revision_changed:
                  summary: Item changed since you read it
                  value:
                    code: asset_revision_changed
                    detail: Inventory changed; review this listing action again
                already_listed:
                  summary: Already on sale
                  value:
                    code: already_listed
                    detail: Item already has a publishable listing
                snapshot_stale:
                  summary: Inventory read too old — includes inventory_proof to poll
                  value:
                    code: snapshot_stale
                    detail: >-
                      The latest complete inventory proof is out of date —
                      refresh your inventory.
                    inventory_proof:
                      status: pending
                      started_at: '2026-10-02T12:00:00.000Z'
                      retry_after_ms: 3000
                idempotency_in_progress:
                  summary: Same key still processing
                  value:
                    code: idempotency_in_progress
                    detail: A request with this Idempotency-Key is still processing.
                idempotency_key_mismatch:
                  summary: Key reused with different details
                  value:
                    code: idempotency_key_mismatch
                    detail: >-
                      This Idempotency-Key was already used with different
                      listing details.
                idempotency_key_consumed:
                  summary: Earlier attempt with this key failed
                  value:
                    code: idempotency_key_consumed
                    detail: >-
                      An earlier attempt with this Idempotency-Key failed. Retry
                      with a new key.
        '422':
          description: >-
            The price is under half of our market price for this item. Over a
            key it cannot be confirmed past — adjust `price_usd` and resend; the
            Idempotency-Key is not spent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                price_below_market:
                  summary: Under half of market
                  value:
                    code: price_below_market
                    detail: >-
                      price_usd 4 is under the minimum 255.16 for this item
                      (market ~510.32). Listings made with an API key cannot go
                      below it.
                    market_usd: 510.32
                    floor_usd: 255.16
                    price_usd: 4
        '429':
          $ref: '#/components/responses/P2PWriteLimited'
        '503':
          $ref: '#/components/responses/P2PDisabled'
components:
  schemas:
    P2PListingRequest:
      type: object
      required:
        - operational_asset_id
        - asset_revision
        - price_usd
      additionalProperties: false
      properties:
        operational_asset_id:
          type: string
          maxLength: 256
          description: The copy to list, from `GET /p2p/inventory`.
          example: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
        asset_revision:
          type: string
          minLength: 16
          maxLength: 128
          description: >-
            From `GET /p2p/inventory`, unchanged. If the item changed since you
            read it, the publish answers `409 asset_revision_changed` — read the
            inventory again.
          example: >-
            sha256:fd0e6de607b774aaaf4d9cdb7e014c003ba614b03f0460b01e8c94bce034bac5
        price_usd:
          type: number
          minimum: 0.1
          maximum: 100000
          multipleOf: 0.01
          description: >-
            Asking price in USD, whole cents (`12.34`; `12.345` is refused, not
            rounded). It may not be under half of our market price for the item
            — see `price_below_market`.
    P2PBatchResult:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            description: >-
              One entry per requested item, in request order. On success:
              `success`, `replay`, `listing`. On failure: `success: false`,
              `status` and the same `code` / `detail` (plus extras such as
              `market_usd` / `floor_usd`) the item would have answered on its
              own.
            properties:
              operational_asset_id:
                type: string
              success:
                type: boolean
              replay:
                type: boolean
                description: >-
                  `true` when the item was already published under this
                  Idempotency-Key and nothing new was listed.
              listing:
                $ref: '#/components/schemas/P2PListing'
              status:
                type: integer
                description: >-
                  On failure: the HTTP status this item alone would have
                  answered.
              code:
                type: string
              detail:
                type: string
        success_count:
          type: integer
        total_requested:
          type: integer
    P2PListing:
      type: object
      properties:
        id:
          type: string
          description: Listing id — use it with `PATCH` / `DELETE /p2p/listings/{id}`.
        status:
          type: string
          description: >-
            `active` — on sale. `trade_pending`, `trade_sent`,
            `verification_hold` — sold and mid-delivery.
            `reconciliation_required` — off the shelf because a full inventory
            read no longer saw the item (`needs_resync: true`).
        price_usd:
          type: number
          description: What the buyer pays.
        currency:
          type: string
          enum:
            - USD
        commission_usd:
          type: number
          description: Our fee on this listing, taken from the seller's side.
        seller_payout_usd:
          type: number
          description: >-
            What a sale credits to your balance: `price_usd` minus
            `commission_usd`.
        market_hash_name:
          type: string
        item_name:
          type: string
        asset_id:
          type: string
          description: Steam asset id of the listed copy.
        operational_asset_id:
          type:
            - string
            - 'null'
        float_value:
          type:
            - number
            - 'null'
        needs_resync:
          type: boolean
          description: >-
            `true` when the listing was taken off the shelf because your
            inventory no longer showed the item. It cannot be revived in place —
            publish the item again once it is back.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - status
        - price_usd
        - currency
        - commission_usd
        - seller_payout_usd
        - market_hash_name
        - asset_id
        - needs_resync
        - created_at
        - updated_at
      example:
        id: cm1xq8z4k0003ab12cd34ef56
        status: active
        price_usd: 12.34
        currency: USD
        commission_usd: 0.25
        seller_payout_usd: 12.09
        market_hash_name: AK-47 | Redline (Field-Tested)
        item_name: AK-47 | Redline (Field-Tested)
        asset_id: '38451927734'
        operational_asset_id: 5b0c1f7e-3d2a-4c8e-9a61-2f4d8b7e1c30
        float_value: 0.2711
        needs_resync: false
        created_at: '2026-10-02T12:04:11.000Z'
        updated_at: '2026-10-02T12:04:11.000Z'
    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:
    Unauthorized:
      description: Missing or invalid API key (`missing_api_key` or `invalid_api_key`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: missing_api_key
            detail: >-
              Provide your API key via `Authorization: Bearer csb_pub_…`.
              Generate one at https://csboard.com/profile?tab=api
    P2PWriteLimited:
      description: >-
        More than 30 P2P writes (publish, reprice, remove) in the current minute
        on this key. Wait `Retry-After` seconds.
      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
            detail: P2P write limit of 30/min exceeded.
    P2PDisabled:
      description: The P2P market is switched off.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            p2p_disabled:
              summary: P2P market unavailable
              value:
                code: p2p_disabled
                detail: The P2P market is not available right now.
  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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.