---
updatedAt: 2026-08-25T16:15:22.000Z
agentTools:
  projectIndex: https://developers.jasper.ai/llms.txt
---

# Update Product by ID

Update a Product in your workspace. Only the attributes you include are changed, so omit an attribute to leave it alone. Note that a `CONTEXT_SOURCE_LIST` attribute such as `Images` is replaced wholesale by the value you send: include the sources you want to keep, and send `[]` to remove all of them.

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "paths": {
    "/v1/products/{productId}": {
      "patch": {
        "description": "Update a Product in your workspace. Only the attributes you include are changed, so omit an attribute to leave it alone. Note that a `CONTEXT_SOURCE_LIST` attribute such as `Images` is replaced wholesale by the value you send: include the sources you want to keep, and send `[]` to remove all of them.",
        "operationId": "updateProduct",
        "parameters": [
          {
            "name": "productId",
            "required": true,
            "in": "path",
            "description": "The Product's unique ID (`prd_`, or legacy `itm_`). Both are accepted.",
            "schema": {
              "example": "prd_073D2D49094A4AED991A47B614522579",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProductRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Product updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductSingleResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad request. May be missing required inputs or may have badly formatted inputs."
          },
          "401": {
            "description": "Unauthorized access to the workspace."
          },
          "403": {
            "description": "Product IQ is not enabled for this workspace."
          },
          "404": {
            "description": "Not found. The product does not exist in your workspace."
          },
          "500": {
            "description": "Internal server error. Unable to update product."
          }
        },
        "security": [
          {
            "X-API-Key": []
          },
          {
            "oauth2": [
              "user"
            ]
          }
        ],
        "summary": "Update Product by ID",
        "tags": [
          "Products"
        ]
      }
    }
  },
  "info": {
    "title": "Jasper API",
    "description": "Jasper API",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Products",
      "description": ""
    }
  ],
  "servers": [
    {
      "url": "https://api.jasper.ai"
    }
  ],
  "components": {
    "securitySchemes": {
      "X-API-Key": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Workspace authentication using API key tokens in the X-API-Key header."
      },
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.jasper.ai/oauth2/authorize",
            "tokenUrl": "https://api.jasper.ai/oauth2/token",
            "refreshUrl": "https://api.jasper.ai/oauth2/token",
            "scopes": {
              "user:read": "Read user information",
              "user": "Read and write user information"
            }
          }
        },
        "description": "User-level authentication using OAuth bearer tokens in the Authorization header."
      }
    },
    "schemas": {
      "ProductAttributeValueInput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The attribute ID (from `GET /products/attributes`).",
            "example": "atr_535B1EC15F5F41EAB1B400E9ED4077B6"
          },
          "value": {
            "description": "The value to set. Its shape is inferred from the attribute's type: string (text), number, boolean, ISO-8601 date string, an option label — or an array of them — (enum / multi-select), an object (key-value), or an array of values for a list-mode attribute. To set categories, use the `Categories` attribute with an array of category names.\n\nFor a `CONTEXT_SOURCE_LIST` attribute (such as the universal `Images`), send an array of source IDs — `[\"csc_…\"]` — returned by `POST /v1/context-sources`. This is the same shape a read returns, so the value from a `GET` can be sent back as-is. The array replaces the whole set, so include the sources you want to keep and omit the ones to remove; send `[]` to remove all. Array order is preserved. Only `FILE` sources (uploaded files) can be attached, and the attribute may narrow that further — `Images` takes PNG and JPEG.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            ],
            "example": "A longer product overview…"
          }
        },
        "required": [
          "id",
          "value"
        ]
      },
      "ProductAttributeValueData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The attribute ID.",
            "example": "atr_535B1EC15F5F41EAB1B400E9ED4077B6"
          },
          "name": {
            "type": "string",
            "description": "The attribute name.",
            "example": "Overview"
          },
          "type": {
            "type": "string",
            "description": "The attribute's normalized core type (matches the `type` from `GET /products/attributes`), or null when unresolved. List-mode attributes report their core type here and return an array `value`.",
            "enum": [
              "TEXT_SHORT",
              "TEXT_LONG",
              "NUMBER",
              "DATE",
              "BOOLEAN",
              "ENUM",
              "KEY_VALUE",
              "JSON",
              "CONTEXT_SOURCE_LIST"
            ],
            "nullable": true,
            "example": "TEXT_LONG"
          },
          "isList": {
            "type": "boolean",
            "description": "Whether the attribute holds a list of values (matches `GET /products/attributes`). When true, `value` is an array.",
            "example": false
          },
          "value": {
            "description": "The attribute value, typed to match `type`: a string (`TEXT_SHORT`/`TEXT_LONG`/`DATE`, and the option label for `ENUM`), a number (`NUMBER`), a boolean (`BOOLEAN`), an object (`KEY_VALUE`/`JSON`), an array of source IDs (`CONTEXT_SOURCE_LIST`, e.g. `Images` — expand one with `GET /v1/context-sources/{sourceId}`), or — for list-mode attributes — an array of the above (e.g. option labels for a multi-select). Null when the attribute is unset.",
            "nullable": true,
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            ],
            "example": "A longer product overview…"
          }
        },
        "required": [
          "id",
          "name",
          "isList"
        ]
      },
      "ProductData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The unique product ID (`prd_`, or legacy `itm_`).",
            "example": "prd_073D2D49094A4AED991A47B614522579"
          },
          "processingState": {
            "type": "string",
            "description": "Processing state of the product.",
            "enum": [
              "inProgress",
              "complete",
              "error"
            ],
            "example": "complete"
          },
          "accessLevel": {
            "type": "string",
            "description": "Who can access the product.",
            "enum": [
              "PRIVATE",
              "PUBLIC"
            ],
            "example": "PRIVATE"
          },
          "contextSourceIds": {
            "description": "The IDs of the sources the product itself was generated from, which are managed in the web app and not settable via this API. Empty when none are attached. Expand one with `GET /v1/context-sources/{sourceId}`. This is separate from the sources held by a `CONTEXT_SOURCE_LIST` attribute such as `Images`, which appear under `attributes` and can be set through this API.",
            "example": [
              "csc_073D2D49094A4AED991A47B614522579"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attributes": {
            "description": "The product's attribute values, including the product name (the `Name` attribute). Categories are included here as the `Categories` attribute (an array of category names).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAttributeValueData"
            }
          },
          "createdAt": {
            "type": "string",
            "example": "2026-06-30T15:38:00.474Z"
          },
          "updatedAt": {
            "type": "string",
            "example": "2026-06-30T15:38:00.474Z"
          }
        },
        "required": [
          "id",
          "processingState",
          "accessLevel",
          "contextSourceIds",
          "attributes",
          "createdAt",
          "updatedAt"
        ]
      },
      "ProductSingleResponseDto": {
        "type": "object",
        "properties": {
          "requestId": {
            "type": "string",
            "example": "bce766ea-a4ef-48e5-9da1-d9602bfecf2d"
          },
          "resource": {
            "type": "string",
            "example": "products"
          },
          "data": {
            "$ref": "#/components/schemas/ProductData"
          }
        },
        "required": [
          "requestId",
          "resource",
          "data"
        ]
      },
      "UpdateProductRequestDto": {
        "type": "object",
        "properties": {
          "accessLevel": {
            "type": "string",
            "enum": [
              "PRIVATE",
              "PUBLIC"
            ],
            "description": "Update who can access the product."
          },
          "attributes": {
            "description": "Attribute values to set or replace. Omit an attribute to leave it unchanged — that is how you update one attribute without disturbing the others. Categories are updated here too, via the `Categories` attribute (an array of category names; pass an empty array to clear all categories). Categories must already exist in the schema editor; unknown names are rejected. Images are updated via the `Images` attribute, whose value is the full set of sources to keep (see `value` below).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAttributeValueInput"
            }
          }
        }
      }
    }
  },
  "x-readme": {
    "metrics-enabled": false
  }
}
```