POST /v1/actions/onetime-product/update-product
Use the Update Status endpoint to change a product’s status (
active/inactive). This endpoint is for content updates only.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 |
prices and media object formats, see Create Product.
Example Request
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",
});
// 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"
// 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);
# 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"
// 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))
// 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);
/* 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);
// 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;
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 | tr -d '\n')
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 | tr -d '\n')
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"
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 | tr -d '\n')
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 | tr -d '\n')
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"
Success Response (200)
{
"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.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.
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 |
| 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) |