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

# Update product inventory

> Set or adjust inventory per variant and location. Each variant succeeds or fails on its own: the call returns 200 and lists any failed variants in `data.errors`. Requires the `admin:products:write` permission.



## OpenAPI

````yaml openapi-merchant.json PATCH /products/{productId}/inventory
openapi: 3.0.0
info:
  title: PuppetVendors Merchant API V2
  version: 2.0.0
  description: >-
    The endpoints reachable with a merchant API key (`mk_live_…`), minted from
    Settings → API Access in the PuppetVendors admin. A merchant key administers
    users and vendors, and renews its own token. Everything else in the V2 API,
    including orders, products, payouts, fulfillments and documents, stays on
    the v1 API token and is refused here with a 403. Keys are revealed once at
    creation; rotating one leaves the previous key working for a 24 hour grace
    window.
  contact:
    name: PuppetVendors Support
    url: https://puppetvendors.com
  license:
    name: Proprietary
servers:
  - url: https://production-api.puppetvendors.com
    description: Production
  - url: http://localhost:8082
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Auth
    description: Authentication endpoints for obtaining and refreshing API tokens
  - name: Portal - Auth
    description: Vendor portal authentication endpoints (vendor user login, token refresh)
  - name: Products
    description: Product management and synchronization
  - name: Merchant Products
    description: >-
      Every vendor's products in your store, read and edited with a merchant API
      key, plus bulk approval and rejection of pending products. A missing
      product returns 404 `PRODUCT_NOT_FOUND`.
  - name: Orders
    description: Order retrieval and management
  - name: Payouts
    description: Vendor payout information
  - name: Fulfillments
    description: Order fulfillment operations
  - name: Reports
    description: Vendor sales reports and analytics
  - name: Vendors
    description: Vendor management operations
  - name: Settings
    description: Settings endpoints for vendor configuration and management
  - name: Users
    description: User account management
  - name: Shop
    description: Shop configuration and settings
  - name: Commissions
    description: Commission rate management
  - name: Integrations
    description: Vendor integration configuration endpoints
  - name: Line Items
    description: Order line item operations
paths:
  /products/{productId}/inventory:
    patch:
      tags:
        - Merchant Products
      summary: Update product inventory
      description: >-
        Set or adjust inventory per variant and location. Each variant succeeds
        or fails on its own: the call returns 200 and lists any failed variants
        in `data.errors`. Requires the `admin:products:write` permission.
      operationId: merchantUpdateProductInventory
      parameters:
        - in: path
          name: productId
          required: true
          schema:
            type: string
          description: >-
            A product ObjectId, a Shopify product GID or a numeric Shopify
            product id. Malformed is 400.
          example: 507f1f77bcf86cd799439021
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductInventoryUpdateRequest'
      responses:
        '200':
          description: Applied per variant; failed variants are listed in data.errors
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      updated:
                        type: integer
                        description: Number of variant and location rows updated
                      errors:
                        type: array
                        description: >-
                          One entry per variant that was not updated. The
                          request still answers 200, so check this.
                        items:
                          type: object
                          properties:
                            variantId:
                              type: string
                            message:
                              type: string
        '400':
          description: >-
            VALIDATION_ERROR, the path, query or body is malformed (including a
            malformed or repeated vendorId). PRODUCT_VALIDATION_FAILED, a
            variantId or inventoryItemId is not on this product; nothing is
            written
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing, invalid or revoked token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            Not a merchant API key, the key lacks admin:products:write, or
            vendorId is not a vendor of this shop
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: >-
            PRODUCT_NOT_FOUND, no product with this id in the shop. The product
            is looked up across the whole shop, and a vendorId does not narrow
            single-product calls (it is only checked to be a vendor of this
            shop, 403 otherwise). A soft-deleted product (status deleted)
            answers 404 too
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    ProductInventoryUpdateRequest:
      type: object
      required:
        - variants
      properties:
        variants:
          type: array
          minItems: 1
          maxItems: 100
          description: Per variant × location quantity updates
          items:
            type: object
            required:
              - variantId
              - locationId
              - quantity
            properties:
              variantId:
                type: string
                description: Shopify variant id, GID, or local subdocument id
              locationId:
                type: string
                description: Location id the quantity applies to
              quantity:
                type: integer
                minimum: -2000000000
                maximum: 2000000000
                description: >-
                  Absolute target in set mode (-1000000000 to 1000000000; may be
                  negative for oversold stock) or a signed delta in adjust mode
                  (-2000000000 to 2000000000). The narrower set-mode range is
                  enforced per request.
              inventoryItemId:
                type: string
                description: Optional; derived from the variant when omitted
              compareQuantity:
                type: integer
                description: Current quantity for optimistic-lock conflict detection
        mode:
          type: string
          enum:
            - set
            - adjust
          default: set
          description: set = absolute quantity; adjust = delta
        reason:
          type: string
          maxLength: 255
          description: Optional audit reason
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          enum:
            - false
          description: Indicates the request failed
        error:
          type: object
          required:
            - message
          properties:
            message:
              type: string
              description: Human-readable error message
              example: Resource not found
            code:
              type: string
              description: >-
                Stable machine-readable error code. The frontend uses this as
                its localisation key (e.g. errors.api.<code>). Server errors
                always report INTERNAL_SERVER_ERROR.
              example: NOT_FOUND
            errorId:
              type: string
              description: >-
                Correlation id for support/log lookup. Present on opaque 5xx
                responses so a user can quote a reference for the underlying
                (server-side logged) error.
              example: err_1783365360839_j281w7b
            details:
              type: object
              description: >-
                Additional client-error context (e.g. field-level validation
                errors). Never populated for server errors.
  securitySchemes:
    bearerAuth:
      type: apiKey
      in: header
      name: x-access-token
      description: >-
        JWT minted from a merchant API key (`mk_live_…`) by POST /authenticate.
        Send the token value directly, with no "Bearer" prefix. Tokens last 14
        days and can be renewed at POST /refresh-token; revoking the key refuses
        the next request made with any token minted from it.

````

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