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

# Request a return for a shipped order

> Creates a return request for an order your store already shipped. By default the return is
created as `TO_BE_DETERMINED` in status `PENDING`: it records what the customer says is coming
back and waits to be reviewed (resolved) by Cubbo or by you. If you already know the outcome,
set `return_type` to `SIMPLE_RETURN` or `EXCHANGE` and the return is resolved in the same call:
the order moves to `returning`, the return moves to `REQUESTED`, the return instructions (RMA
document) are generated and emailed to the customer, and optionally a prepaid return shipping
label is booked with the carrier.

- The order must belong to `store_id`, be in status `shipped`, must not be a pick-and-ship
  order, and must not already have an active (non-cancelled) return.
- Omit `products` (or send `[]`) for a full return: every ordered item at its full ordered
  quantity. Otherwise list the SKUs and quantities coming back; repeated SKUs are summed.
- Kits cannot be returned or exchanged; list the individual products instead.
- `generate_guide` is required whenever `return_type` is not `TO_BE_DETERMINED`. Send
  `false` to resolve without booking a return shipping label (the RMA is still generated).
- For `EXCHANGE`, `exchange_products` lists the replacement items (resolved against your
  store catalog, not the order) and their stock is reserved right away, to ship once the
  return arrives.
- Return-level blockers (order not shipped, return already exists) are reported before
  item-level errors.
- If the return is created but the immediate resolution fails (for example the carrier
  rejects the label), the return stays `PENDING` / `TO_BE_DETERMINED` and the error is
  returned; fetch it with `GET /returns/{return_id}` before retrying, since a second call
  would answer `RETURN_ALREADY_EXISTS`.
- Your API credentials need the permission to create returns;
  ask Cubbo support if the call answers 401 with a valid token.




## OpenAPI

````yaml /openapi.yaml post /returns
openapi: 3.1.0
info:
  title: Cubbo Clients API
  version: '1.0'
  summary: >-
    Orders, inventory, replenishments, returns, shipping and webhooks for Cubbo
    fulfillment.
  description: >
    The Cubbo Clients API connects your store, ERP or marketplace with Cubbo's
    fulfillment network.

    All endpoints except `POST /auth/token` require a bearer token; see the
    Authentication guide.

    Request and response bodies are JSON. Errors are JSON objects with an
    `error` key.
  contact:
    name: Cubbo integrations
    email: integraciones@cubbo.com
servers:
  - url: https://api.cubbo.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: Exchange client credentials for a bearer token.
  - name: Orders
    description: Create, update, hold, cancel and read sales orders.
  - name: Shipping labels
    description: Read the shipping labels generated for an order.
  - name: Inventory
    description: Products and stock per store.
  - name: Lots
    description: Lot-level inventory for products with expiration or batch tracking.
  - name: Reports
    description: Bulk reports for reconciliation.
  - name: Replenishments
    description: Inbound shipments to the warehouse.
  - name: Returns
    description: Returns and exchanges.
  - name: Stores
    description: Store provisioning and settings.
  - name: Shipping methods
    description: Available shipping methods, coverage and quotes.
  - name: Click and collect
    description: Pickup points and in-store pickup orders.
paths:
  /returns:
    post:
      tags:
        - Returns
      summary: Request a return for a shipped order
      description: >
        Creates a return request for an order your store already shipped. By
        default the return is

        created as `TO_BE_DETERMINED` in status `PENDING`: it records what the
        customer says is coming

        back and waits to be reviewed (resolved) by Cubbo or by you. If you
        already know the outcome,

        set `return_type` to `SIMPLE_RETURN` or `EXCHANGE` and the return is
        resolved in the same call:

        the order moves to `returning`, the return moves to `REQUESTED`, the
        return instructions (RMA

        document) are generated and emailed to the customer, and optionally a
        prepaid return shipping

        label is booked with the carrier.


        - The order must belong to `store_id`, be in status `shipped`, must not
        be a pick-and-ship
          order, and must not already have an active (non-cancelled) return.
        - Omit `products` (or send `[]`) for a full return: every ordered item
        at its full ordered
          quantity. Otherwise list the SKUs and quantities coming back; repeated SKUs are summed.
        - Kits cannot be returned or exchanged; list the individual products
        instead.

        - `generate_guide` is required whenever `return_type` is not
        `TO_BE_DETERMINED`. Send
          `false` to resolve without booking a return shipping label (the RMA is still generated).
        - For `EXCHANGE`, `exchange_products` lists the replacement items
        (resolved against your
          store catalog, not the order) and their stock is reserved right away, to ship once the
          return arrives.
        - Return-level blockers (order not shipped, return already exists) are
        reported before
          item-level errors.
        - If the return is created but the immediate resolution fails (for
        example the carrier
          rejects the label), the return stays `PENDING` / `TO_BE_DETERMINED` and the error is
          returned; fetch it with `GET /returns/{return_id}` before retrying, since a second call
          would answer `RETURN_ALREADY_EXISTS`.
        - Your API credentials need the permission to create returns;
          ask Cubbo support if the call answers 401 with a valid token.
      operationId: createReturn
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReturnCreateRequest'
            examples:
              toBeDetermined:
                summary: Request a return to be reviewed later
                value:
                  store_id: 1234
                  order_number: ORD-0001
                  notes: Customer changed their mind
                  products:
                    - sku: SKU-RED-M
                      quantity: 1
              simpleReturnWithLabel:
                summary: Resolve immediately as a simple return with a prepaid label
                value:
                  store_id: 1234
                  order_number: ORD-0001
                  notes: Wrong size
                  return_type: SIMPLE_RETURN
                  generate_guide: true
                  products:
                    - sku: SKU-RED-M
                      quantity: 1
              exchange:
                summary: Resolve immediately as an exchange
                value:
                  store_id: 1234
                  order_number: ORD-0001
                  notes: Wants size L instead of M
                  return_type: EXCHANGE
                  generate_guide: true
                  products:
                    - sku: SKU-RED-M
                      quantity: 1
                  exchange_products:
                    - sku: SKU-RED-L
                      quantity: 1
      responses:
        '201':
          description: >-
            Return created. Only the listed fields are returned;
            `exchange_products` is present only for `EXCHANGE` returns.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReturnCreated'
              examples:
                toBeDetermined:
                  value:
                    id: 98765
                    status: PENDING
                    return_type: TO_BE_DETERMINED
                    notes: Customer changed their mind
                    externally_requested: true
                    expected_products:
                      - product_id: 5551
                        quantity: 1
                        skus:
                          - SKU-RED-M
                    created_at: '2026-10-12T15:04:05.123Z'
                    order_number: ORD-0001
                exchange:
                  value:
                    id: 98766
                    status: REQUESTED
                    return_type: EXCHANGE
                    notes: Wants size L instead of M
                    externally_requested: true
                    expected_products:
                      - product_id: 5551
                        quantity: 1
                        skus:
                          - SKU-RED-M
                    exchange_products:
                      - product_id: 5552
                        quantity: 1
                        skus:
                          - SKU-RED-L
                    created_at: '2026-10-12T15:04:05.123Z'
                    order_number: ORD-0001
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: >-
            Another return request for the same order is still being processed.
            Retry after a moment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReturnError'
              example:
                error: a return request for this order is already in progress
                code: RETURN_REQUEST_IN_FLIGHT
        '422':
          description: >
            Validation or business error. `code` is a stable machine-readable
            identifier (`null` for

            parameter validation errors); `context` carries the offending `sku`
            when relevant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReturnError'
              examples:
                missingParam:
                  value:
                    error: Parameter store_id is required
                    code: null
                    context: null
                missingGenerateGuide:
                  summary: return_type given without generate_guide
                  value:
                    error: Parameter generate_guide is required
                    code: null
                    context: null
                invalidReturnType:
                  summary: >-
                    return_type outside the accepted values (e.g.
                    IMMEDIATE_EXCHANGE)
                  value:
                    error: >-
                      Parameter return_type must be within ["TO_BE_DETERMINED",
                      "SIMPLE_RETURN", "EXCHANGE"]
                    code: null
                    context: null
                storeNotFound:
                  value:
                    error: store 1234 not found
                    code: STORE_NOT_FOUND
                    context: null
                orderNotFound:
                  value:
                    error: order ORD-0001 not found
                    code: ORDER_NOT_FOUND
                    context: null
                returnAlreadyExists:
                  value:
                    error: order already has an active return
                    code: RETURN_ALREADY_EXISTS
                orderNotShipped:
                  value:
                    error: only shipped orders can be returned
                    code: ORDER_NOT_SHIPPED
                pickAndShipNotSupported:
                  value:
                    error: pick and ship orders cannot be returned this way
                    code: PICK_AND_SHIP_NOT_SUPPORTED
                invalidSku:
                  value:
                    error: sku SKU-BLUE-S is not part of order ORD-0001
                    code: INVALID_SKU
                    context:
                      sku: SKU-BLUE-S
                invalidExchangeSku:
                  value:
                    error: sku SKU-BLUE-S is not a product in the store
                    code: INVALID_SKU
                    context:
                      sku: SKU-BLUE-S
                ambiguousSku:
                  value:
                    error: >-
                      sku SKU-RED-M maps to more than one product on order
                      ORD-0001
                    code: AMBIGUOUS_SKU
                    context:
                      sku: SKU-RED-M
                kitNotSupported:
                  value:
                    error: sku KIT-001 is a kit and cannot be returned
                    code: KIT_NOT_SUPPORTED
                    context:
                      sku: KIT-001
                invalidQuantity:
                  value:
                    error: >-
                      quantity 3 for sku SKU-RED-M exceeds the ordered quantity
                      1
                    code: INVALID_QUANTITY
                    context:
                      sku: SKU-RED-M
                      ordered_quantity: 1
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - bearerAuth: []
components:
  schemas:
    ReturnCreateRequest:
      type: object
      required:
        - store_id
        - order_number
        - notes
      properties:
        store_id:
          type: integer
          description: Id of the store that owns the order.
          example: 1234
        order_number:
          type: string
          description: Order number of the shipped order to return.
          example: ORD-0001
        notes:
          type: string
          description: >-
            Reason for the return or any comment to keep with it. Shown on the
            return instructions sent to the customer when the return is
            resolved.
          example: Customer changed their mind
        products:
          type: array
          description: >-
            Items coming back, by SKU. Omit or send an empty array for a full
            return of every ordered item at its full quantity. Repeated SKUs are
            summed. Each SKU must be on the order, map to a single product and
            not be a kit; the quantity cannot exceed the ordered quantity.
          items:
            $ref: '#/components/schemas/ReturnRequestItem'
        return_type:
          type: string
          description: >-
            Outcome of the return. `TO_BE_DETERMINED` (default) creates a
            pending request to be reviewed later. `SIMPLE_RETURN` and `EXCHANGE`
            resolve the return immediately (order moves to `returning`, return
            instructions are emailed to the customer).
          enum:
            - TO_BE_DETERMINED
            - SIMPLE_RETURN
            - EXCHANGE
          default: TO_BE_DETERMINED
          example: TO_BE_DETERMINED
        generate_guide:
          type: boolean
          description: >-
            Required when `return_type` is `SIMPLE_RETURN` or `EXCHANGE`;
            ignored otherwise. `true` books a prepaid return shipping label with
            the carrier and attaches it to the return instructions; `false`
            resolves the return without a label.
          example: true
        exchange_products:
          type: array
          description: >-
            Required when `return_type` is `EXCHANGE`; ignored otherwise.
            Replacement items to ship once the return arrives, by SKU of your
            store catalog (kits not allowed). Their stock is reserved
            immediately.
          items:
            $ref: '#/components/schemas/ReturnRequestItem'
    ReturnCreated:
      type: object
      description: Response of `POST /returns`.
      required:
        - id
        - status
        - return_type
        - notes
        - externally_requested
        - expected_products
        - created_at
        - order_number
      properties:
        id:
          type: integer
          description: Unique id of the return. Use it with the other returns endpoints.
          example: 98765
        status:
          $ref: '#/components/schemas/ReturnStatus'
        return_type:
          $ref: '#/components/schemas/ReturnType'
        notes:
          type: string
          description: The notes you sent.
          example: Customer changed their mind
        externally_requested:
          type: boolean
          description: Always true for returns created through the API.
          example: true
        expected_products:
          type: array
          description: Resolved products and quantities coming back, with their SKUs.
          items:
            $ref: '#/components/schemas/ReturnProduct'
        exchange_products:
          type: array
          description: >-
            Replacement products with their SKUs. Only present for `EXCHANGE`
            returns.
          items:
            $ref: '#/components/schemas/ReturnProduct'
        created_at:
          type: string
          format: date-time
          description: When the return was created.
          example: '2026-10-12T15:04:05.123Z'
        order_number:
          type: string
          description: The order number you sent.
          example: ORD-0001
    ReturnError:
      type: object
      description: >-
        Error body of the create, cancel and decision endpoints, with a
        machine-readable `code`.
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable message.
          example: order already has an active return
        code:
          type:
            - string
            - 'null'
          description: Stable error code; null for parameter validation errors.
          example: RETURN_ALREADY_EXISTS
        context:
          type:
            - object
            - 'null'
          description: >-
            Extra details, when available (for example the offending `sku`).
            Only sent by `POST /returns`.
          example:
            sku: SKU-RED-M
    ReturnRequestItem:
      type: object
      required:
        - sku
        - quantity
      properties:
        sku:
          type: string
          description: SKU of the product.
          example: SKU-RED-M
        quantity:
          type: integer
          minimum: 1
          description: Number of units.
          example: 1
    ReturnStatus:
      type: string
      description: >
        Lifecycle status of a return.

        - `PENDING`: created and waiting for a decision (review of a customer
        request, or decision on an order returned by the carrier).

        - `REQUESTED`: resolved; the customer has the return instructions and
        the goods are expected back.

        - `ORDERED`: resolved by creating a new (replacement or resend) order.

        - `CANCELLED`: cancelled before the goods came back; reserved stock was
        released.

        - `ARRIVED_AT_WAREHOUSE`: the package arrived at the warehouse and is
        waiting to be processed.

        - `AWAITING_INSPECTION`: the package was opened and is waiting for
        inspection of its contents.

        - `RECEIVED`: the goods were checked in and are being re-entered into
        inventory.

        - `REENTERED`: the goods were fully re-entered into inventory; the
        return is complete.

        - `UNSUCCESSFUL`: closed without receiving anything; every expected
        product was missing on reception.
      enum:
        - PENDING
        - REQUESTED
        - ORDERED
        - CANCELLED
        - ARRIVED_AT_WAREHOUSE
        - AWAITING_INSPECTION
        - RECEIVED
        - REENTERED
        - UNSUCCESSFUL
      example: PENDING
    ReturnType:
      type: string
      description: >
        What kind of return this is.

        - `TO_BE_DETERMINED`: requested by the customer or by you, not yet
        reviewed; the outcome (simple return, exchange, rejection) is decided
        later.

        - `SIMPLE_RETURN`: the customer sends the goods back; no replacement is
        shipped.

        - `EXCHANGE`: the customer sends the goods back and replacement items
        (`exchange_products`) are reserved to ship once the return arrives.

        - `IMMEDIATE_EXCHANGE`: replacement items ship right away, before the
        return arrives (created from the Cubbo app, not through this API).

        - `RETURNED_BY_CARRIER`: the carrier could not deliver the order and
        brought it back; decide it with `POST /returns/{return_id}/decision`.

        - `UNIDENTIFIED`: a package arrived at the warehouse that could not be
        matched to an order (created by warehouse staff).
      enum:
        - TO_BE_DETERMINED
        - SIMPLE_RETURN
        - EXCHANGE
        - IMMEDIATE_EXCHANGE
        - RETURNED_BY_CARRIER
        - UNIDENTIFIED
      example: TO_BE_DETERMINED
    ReturnProduct:
      type: object
      description: >-
        A product and quantity declared on a return (expected back, or to be
        shipped as a replacement).
      required:
        - product_id
        - quantity
      properties:
        product_id:
          type: integer
          description: Cubbo id of the product.
          example: 5551
        quantity:
          type: integer
          description: Number of units.
          example: 1
        skus:
          type: array
          description: >-
            SKUs of the product in your store. Present on the returns endpoints;
            absent when the return is embedded in an order.
          items:
            type: string
          example:
            - SKU-RED-M
    Error:
      type: object
      description: Error body returned by every failed request.
      required:
        - error
      properties:
        error:
          type: string
          description: >-
            Human-readable description of the failure. For `401` responses it is
            always `Unauthorized`.
          example: Parameter store_id is required
        message:
          type: string
          description: >-
            Present on `401` responses only; the reason the request was
            rejected.
          example: invalid token
        code:
          type:
            - string
            - 'null'
          description: >-
            Stable machine-readable code, present on some order, return and
            replenishment errors.
          example: ORDER_ALREADY_EXISTS
        context:
          type:
            - object
            - 'null'
          description: >-
            Extra data about the failure when available, for example the id of
            the conflicting order.
          additionalProperties: true
          example:
            order_id: 987654
  responses:
    Unauthorized:
      description: >-
        Missing or invalid token, wrong credentials, or no access to the
        requested store.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalidToken:
              value:
                error: Unauthorized
                message: invalid token
            noHeader:
              value:
                error: Unauthorized
                message: no authorization header found
            storeNotAllowed:
              value:
                error: Unauthorized
                message: not allowed to show? this Store
    InternalServerError:
      description: >-
        Unexpected error. Retry with backoff; if it persists, send the timestamp
        to Cubbo support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: 'unexpected error, timestamp: 1760000000'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Token returned by `POST /auth/token`, sent as `Authorization: Bearer
        <token>`.

````

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