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

# Create resend by SKU

> Enterprise-only. Creates a resend by supplying warehouse-scoped SKU quantities instead of explicit return inventory IDs. The service selects eligible pending return inventory records itself (LIFO by default), then reuses the standard create-resend workflow. The whole request is processed atomically — either every requested unit is allocated and one resend is created, or nothing is.

<Note>
  This is an **Enterprise-only** feature, enabled only for Return Helper Enterprise customers with the SKU inventory module. Requests from accounts that are not enabled are denied. To learn more, contact [enterprise-solution@returnhelper.com](mailto:enterprise-solution@returnhelper.com).
</Note>

Creates a resend by supplying **warehouse-scoped SKU quantities** instead of explicit return inventory IDs.

The request is processed **atomically** — either every requested unit is allocated and a single resend is created, or nothing is created and the call fails. There is no partial resend.

## When to use this vs. Create resend order

* Use **Create resend by SKU** when you track stock by SKU and quantity and don't want to manage individual `returnInventoryId` values.
* Use [Create resend order](/api-reference/resend/create-resend-order) when you already hold the specific `returnInventoryId` values (e.g. cached from the `newInventoryCreated` webhook) that you want to resend.

## Prerequisites

* Your account is enabled for the SKU inventory module (Enterprise).
* Enough resend-eligible inventory exists for each requested SKU in that warehouse. Check the summary first with [Search SKU inventory](/api-reference/skuinventory/search-sku-inventory) (`availableQuantity`), but note that passing the summary check is not a guarantee — see below.
* `shipmentServiceType` is a **shipment** service type (not a *return* service type). Fetch valid codes from [Get available shipment service types for warehouse](/api-reference/shipmentservicetype/get-available-shipment-service-types-for-warehouse).

## How selection works

Allocation happens in three stages, and only the last one is authoritative:

1. **Validation.** Your request lines are normalized (trim + uppercase SKU) and duplicate SKUs are combined. Validation checks `availableQuantity` per `warehouseId` + normalized SKU. Passing this **only** confirms the summary looks sufficient — it does **not** reserve or allocate anything.
2. **Selection.** The service queries real return inventory records that match your `warehouseId`, and normalized SKU and are resend-eligible, then selects exactly the requested quantity using the [pick-up strategy](#pick-up-strategy). If fewer eligible records exist than requested, the whole request is rejected.
3. **Allocation.** Inside a transaction the selected rows are locked and re-checked; if any is no longer eligible the transaction rolls back and the call fails. Otherwise all selected records are advanced to resend / in-progress and the resend is created in the same transaction.

<Warning>
  `SkuInventory.availableQuantity` is an **early check, not a reservation.** Multiple concurrent requests can all pass the same summary check; only the one that successfully locks and claims the underlying records commits. The others fail with a validation error and can be retried. The locked allocation is always the final authority.
</Warning>

## Eligibility rules

A return inventory record is eligible for selection only when it:

* matches the requested `warehouseId`, and the normalized SKU;
* has `handlingStatusCode` = **pending**;
* can transition to resend / in-progress; and
* has **no pending VAS**, including any unfinished VAS Split.

Because eligibility is status-based, the MySQL-eligible count can be **lower** than `availableQuantity` from the summary (which may still count records with pending VAS). When it is, the request fails closed rather than resending an ineligible item.

## Pick-up strategy

Selection uses **LIFO** by default: newest `createOn` first, with the highest return inventory ID as the tie-breaker. The strategy sits behind a factory so it can be switched to FIFO in future without changing allocation logic.

## Errors and retries

* Validation failures come back as HTTP 200 with `meta.status: 400` (the standard soft-error envelope — see [Error handling](/introduction#error-handling)).
* When a SKU has insufficient available quantity, the request is rejected **as a whole**. For security, the error does **not** disclose remaining available quantities.
* When concurrent requests contend for the same stock, the request that fails to lock the records is rejected and can be retried.

## Related

* [Search SKU inventory](/api-reference/skuinventory/search-sku-inventory) — check `availableQuantity` before requesting.
* [Create resend order](/api-reference/resend/create-resend-order) — resend by explicit return inventory IDs; also covers label generation (auto vs manual service types) and cancellation cut-off, which apply to the resend created here too.
* [Cancel resend order](/api-reference/resend/cancel-resend-order) — abort before the warehouse dispatches.
* [Webhooks](/webhooks) — the resend-status-update event delivers lifecycle changes to your endpoint.


## OpenAPI

````yaml post /api/Resend/createResendBySku
openapi: 3.1.0
info:
  title: Return Helper API
  description: API documentation for Return Helper — covering User and Public endpoints.
  version: 1.0.0
servers:
  - url: https://api.returnshelper.com/uat/user
    description: Sandbox — User API
  - url: https://api.returnshelper.com/uat/public
    description: Sandbox — Public API
  - url: https://api.returnhelpercentre.com/v1/user
    description: Production — User API
  - url: https://api.returnhelpercentre.com/v1/public
    description: Production — Public API
  - url: https://api.returnhelperchina.com/user
    description: Production — User API (China)
security:
  - ApiKey: []
    ApiToken: []
paths:
  /api/Resend/createResendBySku:
    post:
      tags:
        - Resend
      summary: Create resend by SKU
      description: >-
        Enterprise-only. Creates a resend by supplying warehouse-scoped SKU
        quantities instead of explicit return inventory IDs. The service selects
        eligible pending return inventory records itself (LIFO by default), then
        reuses the standard create-resend workflow. The whole request is
        processed atomically — either every requested unit is allocated and one
        resend is created, or nothing is.
      operationId: ReturnUserApi_CreateResendBySku
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateResendBySkuRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateResendBySkuResponse'
        '401':
          description: >-
            Authentication failed. Returned when the `x-rr-apikey` or
            `x-rr-apitoken` header is missing or invalid. The body uses the
            standard `ApiResponse` envelope with `meta.error.message` describing
            the auth failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
      security:
        - ApiKey: []
          ApiToken: []
      servers:
        - url: https://api.returnshelper.com/uat/user
          description: Sandbox — User API
components:
  schemas:
    CreateResendBySkuRequest:
      type: object
      description: >-
        Create a resend by warehouse-scoped SKU quantities. `companyName` is not
        part of this request.
      properties:
        warehouseId:
          type: integer
          format: int32
          description: >-
            Warehouse to fulfil the resend from. Must be greater than 0 and
            owned by the authenticated account. All selected inventory comes
            from this single warehouse.
        shipmentServiceType:
          type: string
          description: >-
            Shipment service type code (not a return service type). Non-`others`
            values are validated against the available shipment service and
            service zone for the warehouse and destination.
        itemList:
          type: array
          items:
            $ref: '#/components/schemas/CreateResendBySkuItem'
          description: >-
            Non-empty list of SKU + quantity lines. The number of raw lines is
            limited to 100; the combined quantity across all lines is limited to
            100.
        toAddress:
          $ref: '#/components/schemas/CreateResendBySkuDestinationAddress'
          description: Destination address for the resend shipment.
        sellerReferenceNumber:
          type: string
          maxLength: 50
          description: >-
            Optional seller reference number. When provided, 1-50 characters
            with no invisible characters. Stored on the created resend shipment
            and echoed back in the response.
        description:
          type: string
          description: Optional free-text description for the resend order.
        remarks:
          type: string
          description: Optional free-text merchant remarks for the resend order.
        warehouseRemarks:
          type: string
          description: Optional free-text remarks addressed to the warehouse.
      required:
        - warehouseId
        - shipmentServiceType
        - itemList
        - toAddress
    CreateResendBySkuResponse:
      type: object
      description: >-
        Wraps `CreateResendBySkuReply` under `data`, alongside the standard
        `correlationId` and `meta` envelope.
      properties:
        data:
          $ref: '#/components/schemas/CreateResendBySkuReply'
          description: Create resend by SKU result.
    ApiResponse:
      type: object
      description: >-
        Universal response envelope. Successful responses include the business
        payload as additional top-level fields alongside `correlationId` and
        `meta`. Failed responses (auth errors, validation errors) only populate
        `correlationId` and `meta`, with `meta.errorCode` and `meta.error`
        describing the failure.
      properties:
        correlationId:
          type:
            - string
            - 'null'
          description: >-
            Unique correlation ID for tracing the request through Return Helper
            systems.
        meta:
          $ref: '#/components/schemas/ApiResponseMeta'
    CreateResendBySkuItem:
      type: object
      description: >-
        One requested SKU line. Duplicate SKUs (after trim and uppercase
        normalization) are combined before validation, so their quantities are
        summed.
      properties:
        sku:
          type: string
          maxLength: 32
          description: >-
            SKU to resend. After trim and uppercase normalization must match the
            SKU pattern (alphanumerics plus `#`, `-`, `_`; maximum 32
            characters). Matched against warehouse-scoped SKU inventory.
        quantity:
          type: integer
          description: Number of units of this SKU to resend. Must be greater than 0.
      required:
        - sku
        - quantity
    CreateResendBySkuDestinationAddress:
      type: object
      description: >-
        Destination address for the resend shipment. `addressType` is used only
        for label creation and is not persisted on the resend shipment.
      properties:
        contactName:
          type: string
          maxLength: 100
          description: Recipient contact name. Single line (no tab), 1-100 characters.
        street1:
          type: string
          maxLength: 100
          description: Address line 1. Single line (no tab), 1-100 characters.
        street2:
          type: string
          maxLength: 100
          description: Address line 2. Single line (no tab), 1-100 characters.
        street3:
          type: string
          maxLength: 100
          description: >-
            Address line 3. Optional. When provided, single line (no tab),
            maximum 100 characters.
        city:
          type: string
          maxLength: 50
          description: City. Single line (no tab), 1-50 characters.
        state:
          type: string
          maxLength: 50
          description: State / province. Single line (no tab), 1-50 characters.
        postalCode:
          type: string
          maxLength: 50
          description: >-
            Postal code. 1-50 characters, no leading whitespace. UK postal-code
            format is enforced when `country` is `gbr`.
        country:
          type: string
          description: >-
            Destination country as an ISO3 code (lowercase on the wire, e.g.
            `usa`, `gbr`). Must be a country code accepted by country
            validation.
        phone:
          type: string
          maxLength: 50
          description: >-
            Recipient phone. Single line, 1-50 characters, digits and `+`, `(`,
            `)` only.
        fax:
          type: string
          maxLength: 50
          description: >-
            Recipient fax. Optional. Same format rules as `phone`, maximum 50
            characters.
        email:
          type: string
          maxLength: 100
          description: >-
            Recipient email. Optional. When provided, a valid single-line email,
            maximum 100 characters.
        addressType:
          type: string
          maxLength: 50
          description: >-
            Address type used for label creation (e.g. `business`,
            `residential`). Single line, maximum 50 characters. Not persisted on
            the resend shipment.
      required:
        - contactName
        - street1
        - street2
        - city
        - state
        - postalCode
        - country
        - phone
        - addressType
    CreateResendBySkuReply:
      type: object
      description: >-
        Payload returned under `data` for a successful Create resend by SKU
        call.
      properties:
        resendId:
          type: integer
          format: int64
          description: Created resend identifier.
        resendNumber:
          type: string
          description: System-generated resend number.
        resendShipmentId:
          type: integer
          format: int64
          description: Created resend shipment identifier.
        sellerReferenceNumber:
          type:
            - string
            - 'null'
          description: >-
            Seller reference number supplied in the request, echoed back. `null`
            when none was provided.
        selectedReturnInventoryList:
          type: array
          items:
            $ref: '#/components/schemas/CreateResendBySkuSelectedInventoryItem'
          description: >-
            Flat list of the return inventory records the service allocated to
            this resend, one entry per selected unit.
    ApiResponseMeta:
      type: object
      description: >-
        Application-level metadata for every API response. Inspect `status` and
        `errorCode` to detect soft-error responses (validation failures arrive
        as HTTP 200 with `meta.status: 400`).
      properties:
        status:
          type: integer
          description: >-
            Application-level status code. For successful operations this
            mirrors the HTTP status (e.g. 200). For validation failures it
            reports the logical status (e.g. 400) even though the wire HTTP
            status is 200.
        data:
          type: object
          additionalProperties:
            type: string
          description: Reserved free-form metadata key/value pairs. Usually empty.
        errorCode:
          type:
            - string
            - 'null'
          description: >-
            Machine-readable error code (e.g. `VALIDATION_FAILED`). Non-null
            only when the operation failed.
        error:
          type: object
          additionalProperties: true
          description: >-
            Field-level or message-level error detail keyed by request property
            name. Empty object on success.
    CreateResendBySkuSelectedInventoryItem:
      type: object
      description: A return inventory record the service selected to satisfy the request.
      properties:
        returnInventoryId:
          type: integer
          format: int64
          description: Identifier of the selected return inventory record.
        rmaCode:
          type: string
          description: RMA code of the selected return inventory record.
        sku:
          type: string
          description: Normalized (trimmed, uppercased) SKU of the selected record.
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-rr-apikey
      description: Your API key
    ApiToken:
      type: apiKey
      in: header
      name: x-rr-apitoken
      description: Your API token — keep this private

````