> ## 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/orders/:id/cancel — Cancel an Undelivered Order

> Cancel an order nobody has shipped yet and get the money back on your balance. Opens 31 minutes after purchase for manual delivery, 15 minutes otherwise.

Some orders are delivered by hand: a person (or a slow desk) sends the Steam trade, and that can take up to 12 hours. Such an order shows `delivery_type: "manual"` in `GET /v1/orders` and `GET /v1/orders/{id}`, and it may sit in `delivering` with no trade offer for a long time. `delivery_deadline_at` tells you when the seller's time runs out. If the seller misses it, the order is cancelled and refunded automatically.

If you no longer want to wait, cancel the order yourself. No request body. Cancel is open for:

* **A manual-delivery order** whose seller has sent nothing 31 minutes after purchase.
* **A held order** before its unban, where the source allows it.
* **Any other order** still undelivered 15 minutes after purchase, with no trade offer and nothing in flight upstream.

A player's (P2P) lot cannot be cancelled here. It closes and refunds itself if the seller misses `delivery_deadline_at`.

## Recommended flow

1. Place a buy with `POST /v1/orders` or `POST /v1/market/buy`.
2. Poll `GET /v1/orders/{id}` (or listen for the `order.updated` webhook). Read `delivery_type` and `delivery_deadline_at`.
3. If a `manual` order still has no trade offer and you no longer want it, `POST /v1/orders/{id}/cancel` once 31 minutes have passed.
4. On `425 too_early`, retry after `retry_after_sec`. On `200`, the money is back on your balance. On `202`, it lands within minutes, with the order's next update.

## Responses at a glance

| Status | Meaning |
| - | - |
| `200` `refunded: true` | Cancelled and refunded to your balance. An already cancelled order returns the same answer. |
| `202` `refunded: false` | Cancel placed. The refund lands within minutes, with the order's next update (webhook or `GET /v1/orders/{id}`). |
| `425 too_early` | Cancel is not open yet (31 min for manual delivery, 15 min otherwise). Retry after the returned `retry_after_sec`. |
| `409 offer_sent` | The Steam trade offer is already out. Accept or decline it in Steam. |
| `409 in_progress` | Delivery or a cancel is already running. If delivery fails, the order is refunded automatically. |
| `409 not_cancellable` | The order can no longer be cancelled: delivered, finished, a P2P lot, or not eligible. |
| `429 cancel_limit_reached` | Too many cancels for now. Try again later. |
| `503 cancel_unavailable` | We could not check the order upstream right now. Nothing was changed; retry shortly. |
| `404 order_not_found` | No such order on this account. |

> [!WARNING]
>
> Cancel is idempotent: calling it again on a cancelled order returns the same `200`, never a second refund. Retrying after a network timeout or a `503` is safe.


## OpenAPI

````yaml POST /orders/{id}/cancel
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: Instant Sell
    description: >-
      Sell CS2, Dota 2 and Rust items from any Steam inventory to the CSBoard
      network and get paid to your balance. Invite-only.
  - 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:
  /orders/{id}/cancel:
    post:
      tags:
        - Trading
      summary: Cancel an undelivered order
      description: >-
        Cancel an order nobody has shipped yet; the money goes back to your
        balance. No request body. Cancel opens 31 minutes after purchase for a
        `manual` delivery order whose seller has sent nothing, before the unban
        for a held order (where the source allows it), and 15 minutes after
        purchase for any other order that is still undelivered, with no trade
        offer and nothing in flight upstream. A player's (P2P) lot cannot be
        cancelled here; it is cancelled and refunded automatically if the seller
        misses `delivery_deadline_at`. Idempotent: calling it on an already
        cancelled order returns the same `200`.
      operationId: cancelOrder
      parameters:
        - name: id
          in: path
          required: true
          description: CSBoard order id of the order to cancel.
          schema:
            type: string
      responses:
        '200':
          description: >-
            Cancelled and refunded to your balance. Also the answer for an order
            that was already cancelled.
          content:
            application/json:
              schema:
                type: object
                properties:
                  order_id:
                    type: string
                  cancelled:
                    type: boolean
                  refunded:
                    type: boolean
                    description: >-
                      `true`: the money is already back on your balance.
                      `false`: the cancel is placed and the refund lands with
                      the order's next update.
                  detail:
                    type: string
                    description: Present when the refund is still on its way (`202`).
                required:
                  - order_id
                  - cancelled
                  - refunded
              example:
                order_id: ord_01J9Z3K8Q2
                cancelled: true
                refunded: true
        '202':
          description: >-
            Cancel placed. The refund lands on your balance within minutes and
            shows up with the order's next update (`order.updated` webhook, `GET
            /orders/{id}`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  order_id:
                    type: string
                  cancelled:
                    type: boolean
                  refunded:
                    type: boolean
                    description: >-
                      `true`: the money is already back on your balance.
                      `false`: the cancel is placed and the refund lands with
                      the order's next update.
                  detail:
                    type: string
                    description: Present when the refund is still on its way (`202`).
                required:
                  - order_id
                  - cancelled
                  - refunded
              example:
                order_id: ord_01J9Z3K8Q2
                cancelled: true
                refunded: false
                detail: >-
                  Cancel placed; the refund lands on your balance within
                  minutes.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: No order with that id on this account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: order_not_found
                detail: No such order on this account.
        '409':
          description: >-
            The order cannot be cancelled. `offer_sent`: the Steam trade offer
            is already out — accept or decline it in Steam. `in_progress`:
            delivery or a cancel is already running; if delivery fails the order
            is refunded automatically. `not_cancellable`: the order is
            delivered, finished, a player's (P2P) lot, or not eligible.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                offer_sent:
                  summary: Trade offer already sent
                  value:
                    code: offer_sent
                    detail: >-
                      The Steam trade offer is already out; accept or decline it
                      in Steam.
                in_progress:
                  summary: Delivery or cancel already running
                  value:
                    code: in_progress
                    detail: >-
                      Delivery is in progress; if it fails, the order is
                      refunded automatically.
                not_cancellable:
                  summary: No longer cancellable
                  value:
                    code: not_cancellable
                    detail: This order can no longer be cancelled.
        '425':
          description: >-
            Cancel is not open yet: 31 minutes after purchase for `manual`
            delivery, 15 minutes otherwise. Retry after `retry_after_sec`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                  detail:
                    type: string
                  retry_after_sec:
                    type: integer
                    description: Seconds until cancel opens.
              example:
                code: too_early
                detail: Cancel opens 15 minutes after purchase.
                retry_after_sec: 540
        '429':
          description: >-
            `cancel_limit_reached`: too many cancels for now — try again later.
            `rate_limit_exceeded`: the per-key trading budget is spent — wait
            `Retry-After` seconds.
          headers:
            Retry-After:
              description: Seconds to wait before retrying (on `rate_limit_exceeded`).
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                cancel_limit_reached:
                  summary: Too many cancels
                  value:
                    code: cancel_limit_reached
                    detail: Cancel limit reached for now; try again later.
                rate_limit_exceeded:
                  summary: Rate limit
                  value:
                    code: rate_limit_exceeded
                    detail: Trading rate limit of 10000 requests/min exceeded.
        '503':
          description: >-
            The order could not be checked upstream right now. Nothing was
            changed; retry shortly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: cancel_unavailable
                detail: >-
                  The order could not be checked upstream right now and nothing
                  was changed; retry shortly.
components:
  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
  schemas:
    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
  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.