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

# Update product

> Updates a product and returns the full record. Allows partial update: send only the fields to change, omitted fields are left unchanged, and passing `tax_codes: []` clears the product specific codes so organization default applies. `source_id`, `source`, `source_account_id` and the timestamps are immutable. `source_updated_at` cannot move backwards - a stale value is a 422 carrying the current one. Answers 404 for an unknown id or one owned by another account. Last-write-wins; no idempotency guarantee.

### Partial updates

This endpoint only updates the fields you provide; omitted fields are left unchanged.


## OpenAPI

````yaml PATCH /products/{product_id}
openapi: 3.1.0
info:
  title: Taxwire Public API
  version: 0.1.0
servers: []
security: []
paths:
  /products/{product_id}:
    patch:
      tags:
        - Products
      summary: Update a Product
      description: >-
        Updates a product and returns the full record. Allows partial update:
        send only the fields to change, omitted fields are left unchanged, and
        passing `tax_codes: []` clears the product specific codes so
        organization default applies. `source_id`, `source`, `source_account_id`
        and the timestamps are immutable. `source_updated_at` cannot move
        backwards - a stale value is a 422 carrying the current one. Answers 404
        for an unknown id or one owned by another account. Last-write-wins; no
        idempotency guarantee.
      operationId: update_product_products__product_id__patch
      parameters:
        - name: product_id
          in: path
          required: true
          schema:
            type: string
            description: The product's Taxwire `id` (a `prd_`-prefixed ULID).
            title: Product Id
          description: The product's Taxwire `id` (a `prd_`-prefixed ULID).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductUpdateRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductResource'
        '422':
          description: Validation Error - Invalid input data
          content:
            application/json:
              schema:
                properties:
                  detail:
                    items:
                      properties:
                        type:
                          type: string
                        loc:
                          items:
                            type: string
                          type: array
                        msg:
                          type: string
                        input:
                          oneOf:
                            - type: string
                            - type: number
                            - type: boolean
                            - type: 'null'
                      type: object
                    type: array
                type: object
              example:
                detail:
                  - type: string_type
                    loc:
                      - body
                      - line_items
                      - 0
                      - quantity
                    msg: Input should be a valid string
                    input: 1
        '429':
          description: Rate limit exceeded. Try again later.
          headers:
            Retry-After:
              schema:
                type: string
              description: Time in seconds until the rate limit resets
            X-RateLimit-Limit:
              schema:
                type: string
              description: The rate limit ceiling for the given request
            X-RateLimit-Remaining:
              schema:
                type: string
              description: The number of requests remaining in the time window
          content:
            application/json:
              schema:
                properties:
                  detail:
                    type: string
                    example: Rate limit exceeded
                type: object
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: string
              example: Internal Server Error
      security:
        - APIKeyHeader: []
        - HTTPBearer: []
components:
  schemas:
    ProductUpdateRequest:
      properties:
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: New product name. Non-blank; omit to leave unchanged.
          examples:
            - Organic Coffee Beans
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: New description; `null` clears it. Omit to leave unchanged.
          examples:
            - 12 oz bag of roasted coffee beans
        source_category:
          anyOf:
            - type: string
            - type: 'null'
          title: Source Category
          description: >-
            New source category; `null` clears it. Omit to leave unchanged. Not
            a tax code and never used in a calculation.
          examples:
            - Food & Beverage > Coffee
        tax_codes:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Tax Codes
          description: >-
            Replace the assigned tax codes. `[]` clears the override so the
            company default applies; omit to leave unchanged.
          examples:
            - - TANGIBLE_PERSONAL_PROPERTY.FOOD
        source_updated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Source Updated At
          description: >-
            New source-system watermark. Timezone-aware, an older value than
            current is rejected with 422. Not clearable; omit to leave
            unchanged.
          examples:
            - '2026-09-14T19:58:12Z'
      additionalProperties: false
      type: object
      title: ProductUpdateRequest
      description: >-
        The fields to change on a product.


        A direct partial update: every field is optional, an omitted field is
        left

        unchanged, and the endpoint makes no idempotency or side-effect
        guarantees

        beyond writing what is sent. Only mutable fields listed here.
    ProductResource:
      properties:
        id:
          type: string
          title: Id
          description: Taxwire's stable identifier for the product.
          examples:
            - prd_01J9Z8Q4E7K2M3N4P5R6S7T8U9
        source_id:
          type: string
          title: Source Id
          description: >-
            Your identifier for the product in the system it came from (a SKU, a
            Stripe product id).
          examples:
            - SKU-123
            - prd_2344536
        source:
          type: string
          enum:
            - business_central
            - campfire
            - maxio
            - monetizenow
            - netsuite
            - quickbooks
            - rillet
            - salesbricks
            - shopify
            - stripe
            - taxwire
            - xero
          description: >-
            The system the product came from. `taxwire` for products you send
            directly to this API.
          examples:
            - taxwire
            - stripe
        source_account_id:
          type: string
          title: Source Account Id
          description: >-
            The account the product belongs to within `source`, for sources that
            have more than one. `__default__` when the source has a single
            account.
          examples:
            - acct_234234
        name:
          type: string
          title: Name
          description: The product's name.
          examples:
            - Organic Coffee Beans
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: The product's description, if any.
          examples:
            - 12 oz bag of roasted coffee beans
        source_category:
          anyOf:
            - type: string
            - type: 'null'
          title: Source Category
          description: >-
            The product's category in the source system, kept for
            identification. Not a tax code and never used in a calculation.
          examples:
            - Food & Beverage > Coffee
        tax_codes:
          items:
            type: string
          type: array
          title: Tax Codes
          description: >-
            The tax codes you assigned to the product. Empty means no
            product-level assignment, so the organization default applies.
          examples:
            - - TANGIBLE_PERSONAL_PROPERTY.FOOD
        resolved_tax_codes:
          items:
            type: string
          type: array
          title: Resolved Tax Codes
          description: >-
            The tax codes actually used for the product during a calculation:
            `tax_codes` when set, otherwise your organization default. Never
            empty.
          examples:
            - - TANGIBLE_PERSONAL_PROPERTY
        source_updated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Source Updated At
          description: >-
            When the product last changed in the source system, as reported by
            the sender. Null when unknown.
          examples:
            - '2026-09-14T19:58:12Z'
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When Taxwire first stored the product.
          examples:
            - '2026-09-14T20:00:00Z'
        updated_at:
          type: string
          format: date-time
          title: Updated At
          description: >-
            When the product was last changed in Taxwire. Equals `created_at`
            until the first change.
          examples:
            - '2026-09-14T20:00:00Z'
      additionalProperties: false
      type: object
      required:
        - id
        - source_id
        - source
        - source_account_id
        - name
        - resolved_tax_codes
        - created_at
        - updated_at
      title: ProductResource
      description: A product in your Taxwire catalog and the tax codes assigned to it.
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
    HTTPBearer:
      type: http
      scheme: bearer

````

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