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

# Update Product

> Update a one-time product's content with automatic immutable versioning

Update a one-time product's content. If the content has changed, a new immutable version is created automatically. If the content is identical to the current version, no new version is created.

```
POST /v1/actions/onetime-product/update-product
```

**Authentication:** API Key

<Warning>
  Use the [Update Status](/api-reference/endpoints/onetime-products/update-status) endpoint to change a product's status (`active`/`inactive`). This endpoint is for content updates only.
</Warning>

## Request Body

| Field         | Type           | Required | Description                                                                                     |
| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------- |
| `id`          | string         | Yes      | Product ID (Short ID format `PROD_xxx`)                                                         |
| `name`        | string         | No       | Updated product name (max 64 chars)                                                             |
| `description` | string \| null | No       | Updated description (pass `null` or `""` to clear)                                              |
| `prices`      | object         | No       | Updated multi-currency pricing map                                                              |
| `media`       | array          | No       | Updated media items                                                                             |
| `successUrl`  | string \| null | No       | Updated redirect URL (max 512 chars, must be a valid http(s) URL; pass `null` or `""` to clear) |
| `metadata`    | object         | No       | Updated custom metadata                                                                         |

For the `prices` and `media` object formats, see [Create Product](/api-reference/endpoints/onetime-products/create-product#price-object-format).

## Example Request

<CodeGroup>
  ```typescript SDK theme={"system"}
  const { product } = await client.onetimeProducts.update({
    id: "PROD_3kF9mNpQrStUvWxYz1A2bC",
    name: "Premium Template Pack v2",
    description: "75 premium design templates — expanded collection.",
    prices: {
      USD: { amount: "59.00", taxIncluded: false, taxCategory: TaxCategory.DigitalGoods },
      EUR: { amount: "55.00", taxIncluded: true, taxCategory: TaxCategory.DigitalGoods },
    },
    successUrl: "https://example.com/thank-you",
  });
  ```

  ```typescript TypeScript (fetch) theme={"system"}
  // Uses callApi() helper from authentication.mdx
  const result = await callApi("POST", "/v1/actions/onetime-product/update-product", {
    id: "PROD_3kF9mNpQrStUvWxYz1A2bC",
    name: "Premium Template Pack v2",
    description: "75 premium design templates — expanded collection.",
    prices: {
      USD: { amount: "59.00", taxIncluded: false, taxCategory: "digital_goods" },
      EUR: { amount: "55.00", taxIncluded: true, taxCategory: "digital_goods" },
    },
    successUrl: "https://example.com/thank-you",
  });
  console.log(result.data.product.name); // => "Premium Template Pack v2"
  ```

  ```java Java theme={"system"}
  // Uses callApi() helper from authentication.mdx
  String body = """
      {
        "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
        "name": "Premium Template Pack v2",
        "description": "75 premium design templates — expanded collection.",
        "prices": {
          "USD": { "amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods" },
          "EUR": { "amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods" }
        },
        "successUrl": "https://example.com/thank-you"
      }""";

  String response = callApi("POST", "/v1/actions/onetime-product/update-product", body);
  System.out.println(response);
  ```

  ```python Python theme={"system"}
  # Uses call_api() helper from authentication.mdx
  result = call_api("POST", "/v1/actions/onetime-product/update-product", {
      "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
      "name": "Premium Template Pack v2",
      "description": "75 premium design templates — expanded collection.",
      "prices": {
          "USD": {"amount": "59.00", "taxIncluded": False, "taxCategory": "digital_goods"},
          "EUR": {"amount": "55.00", "taxIncluded": True, "taxCategory": "digital_goods"},
      },
      "successUrl": "https://example.com/thank-you",
  })
  print(result["data"]["product"]["name"])  # => "Premium Template Pack v2"
  ```

  ```go Go theme={"system"}
  // Uses callAPI() helper from authentication.mdx
  body := map[string]interface{}{
      "id":   "PROD_3kF9mNpQrStUvWxYz1A2bC",
      "name": "Premium Template Pack v2",
      "description": "75 premium design templates — expanded collection.",
      "prices": map[string]interface{}{
          "USD": map[string]interface{}{"amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods"},
          "EUR": map[string]interface{}{"amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods"},
      },
      "successUrl": "https://example.com/thank-you",
  }
  result, err := callAPI("POST", "/v1/actions/onetime-product/update-product", body)
  if err != nil {
      log.Fatal(err)
  }
  fmt.Println(string(result))
  ```

  ```rust Rust theme={"system"}
  // Uses call_api() helper from authentication.mdx
  let body = serde_json::json!({
      "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
      "name": "Premium Template Pack v2",
      "description": "75 premium design templates — expanded collection.",
      "prices": {
          "USD": { "amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods" },
          "EUR": { "amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods" }
      },
      "successUrl": "https://example.com/thank-you"
  });
  let result = call_api("POST", "/v1/actions/onetime-product/update-product", &body).await?;
  println!("{}", result);
  ```

  ```c C theme={"system"}
  /* Uses call_api() helper from authentication.mdx */
  const char *body =
      "{\"id\":\"PROD_3kF9mNpQrStUvWxYz1A2bC\","
      "\"name\":\"Premium Template Pack v2\","
      "\"description\":\"75 premium design templates — expanded collection.\","
      "\"prices\":{\"USD\":{\"amount\":\"59.00\",\"taxIncluded\":false,\"taxCategory\":\"digital_goods\"},"
      "\"EUR\":{\"amount\":\"55.00\",\"taxIncluded\":true,\"taxCategory\":\"digital_goods\"}},"
      "\"successUrl\":\"https://example.com/thank-you\"}";
  char *response = call_api("POST", "/v1/actions/onetime-product/update-product", body);
  printf("%s\n", response);
  free(response);
  ```

  ```cpp C++ theme={"system"}
  // Uses callApi() helper from authentication.mdx
  std::string body = R"({
    "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
    "name": "Premium Template Pack v2",
    "description": "75 premium design templates — expanded collection.",
    "prices": {
      "USD": { "amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods" },
      "EUR": { "amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods" }
    },
    "successUrl": "https://example.com/thank-you"
  })";
  std::string response = callApi("POST", "/v1/actions/onetime-product/update-product", body);
  std::cout << response << std::endl;
  ```

  ```bash cURL theme={"system"}
  MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
  TIMESTAMP=$(date +%s)
  BODY='{
    "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
    "name": "Premium Template Pack v2",
    "description": "75 premium design templates — expanded collection.",
    "prices": {
      "USD": { "amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods" },
      "EUR": { "amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods" }
    },
    "successUrl": "https://example.com/thank-you"
  }'
  BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
  CANONICAL_REQUEST="POST
  /v1/actions/onetime-product/update-product
  $TIMESTAMP
  $BODY_HASH"

  SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

  curl -X POST "https://api.waffo.ai/v1/actions/onetime-product/update-product" \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $MERCHANT_ID" \
    -H "X-Timestamp: $TIMESTAMP" \
    -H "X-Signature: $SIGNATURE" \
    -d "$BODY"
  ```

  ```bash wget theme={"system"}
  MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
  TIMESTAMP=$(date +%s)
  BODY='{
    "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
    "name": "Premium Template Pack v2",
    "description": "75 premium design templates — expanded collection.",
    "prices": {
      "USD": { "amount": "59.00", "taxIncluded": false, "taxCategory": "digital_goods" },
      "EUR": { "amount": "55.00", "taxIncluded": true, "taxCategory": "digital_goods" }
    },
    "successUrl": "https://example.com/thank-you"
  }'
  BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
  CANONICAL_REQUEST="POST
  /v1/actions/onetime-product/update-product
  $TIMESTAMP
  $BODY_HASH"

  SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

  wget -qO- "https://api.waffo.ai/v1/actions/onetime-product/update-product" \
    --header="Content-Type: application/json" \
    --header="X-Merchant-Id: $MERCHANT_ID" \
    --header="X-Timestamp: $TIMESTAMP" \
    --header="X-Signature: $SIGNATURE" \
    --post-data="$BODY"
  ```
</CodeGroup>

## Success Response (200)

```json theme={"system"}
{
  "data": {
    "product": {
      "id": "PROD_3kF9mNpQrStUvWxYz1A2bC",
      "storeId": "STO_2aUyqjCzEIiEcYMKj7TZtw",
      "name": "Premium Template Pack v2",
      "description": "75 premium design templates — expanded collection.",
      "prices": {
        "USD": { "amount": "59.00", "taxCategory": "digital_goods" },
        "EUR": { "amount": "55.00", "taxCategory": "digital_goods" }
      },
      "media": [],
      "successUrl": "https://example.com/thank-you",
      "metadata": {},
      "status": "active",
      "createdAt": "2026-01-15T10:30:00.000Z",
      "updatedAt": "2026-01-15T11:00:00.000Z"
    }
  }
}
```

## Response Fields

Same as [Create Product response](/api-reference/endpoints/onetime-products/create-product#response-fields).

<Note>
  Product versions are **immutable**. Existing orders retain their original version. New purchases always use the latest version. If the submitted content is identical to the current version, no new version is created and the existing version is returned.
</Note>

## Errors

> **Retry policy:** Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).

| Status | `errors[0].message`                         | What it means                                                                                               | Recommended handling                                                                                                                 |
| ------ | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| 400    | `Missing required field: id`                | `id` not provided                                                                                           | Fix the body, resubmit                                                                                                               |
| 400    | `Invalid ID format`                         | The provided Short ID could not be decoded                                                                  | Fix the `id` format, resubmit                                                                                                        |
| 400    | `Invalid currency code`                     | Currency code must be exactly 3 uppercase letters (ISO 4217, e.g. `USD`, `EUR`, `JPY`)                      | Use a valid ISO 4217 code, resubmit                                                                                                  |
| 400    | `Invalid amount`                            | Amount must be a positive number string (e.g. `"9.99"`, `"100"`)                                            | Use a positive number string, resubmit                                                                                               |
| 400    | `Product X has no version in environment Y` | The product has no version in the targeted environment (e.g. attempting to update `prod` before publishing) | Publish the product to the target environment first via [Publish Product](/api-reference/endpoints/onetime-products/publish-product) |
| 404    | `Product not found`                         | Product does not exist or is not accessible                                                                 | Verify the `id` belongs to your merchant account                                                                                     |
| 500    | `Internal server error`                     | Unexpected server-side failure                                                                              | Retry with exponential backoff (start 5s, max 3 attempts)                                                                            |
