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

# Update a product

> Only touches the fields present in the body. Sending `null` clears a field; omitting it leaves it unchanged. Variants cannot be patched — send them on create, or the whole list would be replaced by a partial one.



## OpenAPI

````yaml https://api.trama.so/v1/openapi.json patch /v1/catalog/products/{productId}
openapi: 3.1.0
info:
  description: >-
    Trama's REST API. Authenticate with an organization API key, created under
    Settings → Developers, and send it as `Authorization: Bearer <key>` (or in
    the `x-api-key` header).


    Every key is bound to ONE organization: everything this API returns and
    everything it writes stays inside that organization, and no request ever
    names it.


    Errors always come back as `{ "error": { "code", "message" } }`. Branch on
    `code` — it is stable; the `message` text is not.
  title: Trama API
  version: 1.0.0
servers:
  - url: https://api.trama.so
security:
  - bearerAuth: []
  - apiKeyHeader: []
paths:
  /v1/catalog/products/{productId}:
    patch:
      tags:
        - Catalog
      summary: Update a product
      description: >-
        Only touches the fields present in the body. Sending `null` clears a
        field; omitting it leaves it unchanged. Variants cannot be patched —
        send them on create, or the whole list would be replaced by a partial
        one.
      parameters:
        - schema:
            type: string
          required: true
          in: path
          name: productId
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                budgetTier:
                  type:
                    - string
                    - 'null'
                  enum:
                    - economic
                    - mid
                    - premium
                    - null
                capacityMax:
                  type:
                    - integer
                    - 'null'
                  exclusiveMinimum: 0
                capacityMin:
                  type:
                    - integer
                    - 'null'
                  exclusiveMinimum: 0
                currency:
                  type:
                    - string
                    - 'null'
                  minLength: 3
                  maxLength: 3
                  example: USD
                description:
                  type:
                    - string
                    - 'null'
                durationDays:
                  type:
                    - integer
                    - 'null'
                  exclusiveMinimum: 0
                durationHours:
                  type:
                    - number
                    - 'null'
                  exclusiveMinimum: 0
                excludes:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                externalReferenceCode:
                  type:
                    - string
                    - 'null'
                  description: >-
                    The code the agency uses for this product in THEIR system.
                    It is what makes syncing possible without storing Trama's
                    ids.
                fromPrice:
                  type:
                    - number
                    - 'null'
                  minimum: 0
                includes:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                operator:
                  type:
                    - string
                    - 'null'
                priceBasis:
                  type:
                    - string
                    - 'null'
                priceMax:
                  type:
                    - number
                    - 'null'
                  minimum: 0
                pricingMode:
                  type: string
                  enum:
                    - per_person
                    - per_group
                    - total
                  default: per_person
                shortDescription:
                  type:
                    - string
                    - 'null'
                specialConditions:
                  type:
                    - string
                    - 'null'
                status:
                  type: string
                  enum:
                    - active
                    - paused
                    - draft
                  default: active
                title:
                  type: string
                  minLength: 1
                type:
                  type: string
                  enum:
                    - package
                    - experience
                    - expedition
                    - custom
                  default: package
                validFrom:
                  type:
                    - string
                    - 'null'
                  example: '2026-01-01'
                validUntil:
                  type:
                    - string
                    - 'null'
                  example: '2026-12-31'
      responses:
        '200':
          description: The updated product.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogProduct'
        '400':
          description: The request is not valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: The API key is missing or not valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: The resource does not exist in this organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict with the current state of the resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: The API key exceeded its request limit. Retry later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    CatalogProduct:
      type: object
      properties:
        budgetTier:
          type:
            - string
            - 'null'
          enum:
            - economic
            - mid
            - premium
            - null
        capacityMax:
          type:
            - integer
            - 'null'
        capacityMin:
          type:
            - integer
            - 'null'
        coverImage:
          type:
            - string
            - 'null'
        createdAt:
          type: string
          format: date-time
        currency:
          type:
            - string
            - 'null'
        description:
          type:
            - string
            - 'null'
        destinations:
          type: array
          items:
            type: string
        durationDays:
          type:
            - integer
            - 'null'
        durationHours:
          type:
            - number
            - 'null'
        excludes:
          type: array
          items:
            type: string
        externalReferenceCode:
          type:
            - string
            - 'null'
          description: >-
            The code the agency uses for this product in THEIR system. It is
            what makes syncing possible without storing Trama's ids.
        fromPrice:
          type:
            - number
            - 'null'
        gallery:
          type: array
          items:
            type: string
        id:
          type: string
        includes:
          type: array
          items:
            type: string
        operator:
          type:
            - string
            - 'null'
        priceBasis:
          type:
            - string
            - 'null'
        priceMax:
          type:
            - number
            - 'null'
        pricingMode:
          type: string
          enum:
            - per_person
            - per_group
            - total
        shortDescription:
          type:
            - string
            - 'null'
        specialConditions:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - active
            - paused
            - draft
        title:
          type: string
        type:
          type: string
          enum:
            - package
            - experience
            - expedition
            - custom
        updatedAt:
          type: string
          format: date-time
        validFrom:
          type:
            - string
            - 'null'
        validUntil:
          type:
            - string
            - 'null'
        variants:
          type: array
          items:
            $ref: '#/components/schemas/CatalogProductVariant'
      required:
        - budgetTier
        - capacityMax
        - capacityMin
        - coverImage
        - createdAt
        - currency
        - description
        - destinations
        - durationDays
        - durationHours
        - excludes
        - externalReferenceCode
        - fromPrice
        - gallery
        - id
        - includes
        - operator
        - priceBasis
        - priceMax
        - pricingMode
        - shortDescription
        - specialConditions
        - status
        - title
        - type
        - updatedAt
        - validFrom
        - validUntil
        - variants
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ApiError'
      required:
        - error
    CatalogProductVariant:
      type: object
      properties:
        capacityMax:
          type:
            - integer
            - 'null'
        capacityMin:
          type:
            - integer
            - 'null'
        currency:
          type:
            - string
            - 'null'
        description:
          type:
            - string
            - 'null'
        durationDays:
          type:
            - integer
            - 'null'
        durationHours:
          type:
            - number
            - 'null'
        excludes:
          type: array
          items:
            type: string
        fromPrice:
          type:
            - number
            - 'null'
        id:
          type: string
        includes:
          type: array
          items:
            type: string
        label:
          type: string
        position:
          type: integer
        priceMax:
          type:
            - number
            - 'null'
        shortDescription:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - active
            - paused
            - draft
      required:
        - capacityMax
        - capacityMin
        - currency
        - description
        - durationDays
        - durationHours
        - excludes
        - fromPrice
        - id
        - includes
        - label
        - position
        - priceMax
        - shortDescription
        - status
    ApiError:
      type: object
      properties:
        code:
          type: string
          description: >-
            A stable, machine-readable code. Branch on this — the `message` text
            may change, the code will not.
          example: CATALOG_PRODUCT_NOT_FOUND
        message:
          type: string
          example: The catalog product does not exist.
      required:
        - code
        - message
  securitySchemes:
    bearerAuth:
      bearerFormat: API key
      description: 'The organization API key, sent as `Authorization: Bearer <key>`.'
      scheme: bearer
      type: http
    apiKeyHeader:
      description: The same API key, sent in the `x-api-key` header.
      in: header
      name: x-api-key
      type: apiKey

````