# RevCent MCP Operation: `CreateProduct`

This document explains how MCP/AI clients should use the `CreateProduct` operation in RevCent.

`CreateProduct` creates a new Product catalog record and returns a 20-character `product_id`.

Before creating Products, MCP/AI should read the Products overview:

```text
https://revcent.com/documentation/markdown/mcp/operation/OverviewProduct.md
```

MCP/AI should also understand the Product and Product Bundle KB pages:

```text
https://kb.revcent.com/en/product
https://kb.revcent.com/product/product-bundle
```

Sources:
- Refreshed RevCent operation schema for `CreateProduct`
- Refreshed RevCent operation schema for `EditProduct`
- Refreshed RevCent operation schema for `GetUserShop`
- Products overview: `https://revcent.com/documentation/markdown/mcp/operation/OverviewProduct.md`
- Product KB: `https://kb.revcent.com/en/product`
- Product Bundle KB: `https://kb.revcent.com/product/product-bundle`

---

## Operation Summary

Use `CreateProduct` when the user wants to create a Product that does not already exist.

A Product may be:

```text
Physical.
Digital.
Subscription-based.
Trial-based.
A bundle Product.
A third-party shop Product.
A parent Product.
A child/variant Product.
A listing-ready or agentic-commerce Product.
```

Creating a Product affects:

```text
Checkout pricing.
Product Sales.
Fulfillment.
Shipping.
Subscription renewals.
Trial expirations.
Bundle decomposition.
Customer-facing Product images.
Email Templates.
Customer Portals.
Customer support.
AI Assistants.
AI Voice Agents.
Functions.
BigQuery reporting.
```

Do not create duplicates. If a Product may already exist, verify whether it already exists before creating a new one.

This is especially important when importing Products from a user third-party shop such as WooCommerce. For WooCommerce imports, MCP/AI should use the `GetUserShop` operation with `remote_data: ["products"]` and rely on the returned `exists_in_revcent` property to decide whether to create or edit the Product.

If `exists_in_revcent = true`, do not call `CreateProduct`; use `EditProduct` only if updates are needed.

If `exists_in_revcent = false`, the Product may be created with `CreateProduct`, preserving the remote shop Product ID as `internal_id` and the RevCent User Shop ID as `third_party_shop`.

---

# Required Fields

`CreateProduct` requires:

| Field | Type | Description |
|---|---:|---|
| `name` | string | Product name. |
| `price` | number | Actual Product transaction price. |
| `sku` | string | Product SKU. |

Minimum valid request:

```json
{
  "name": "Organic Coffee Beans - 2 lb Bag",
  "price": 29.99,
  "sku": "COFFEE-2LB"
}
```

---

# Schema Rule: No Unknown Fields

`CreateProduct` uses:

```text
additionalProperties = false
```

Only send fields supported by the operation schema.

Do not send unsupported fields such as:

```text
image
images
image_file
metadata
inventory_policy
warehouse_id
category_name
random custom fields
```

If Product metadata is needed and `CreateProduct` does not include a `metadata` input field, create the Product first and then use the appropriate metadata operation if supported for Product items.

---

# Read the Overview and KB First

The Product overview and KB pages are important because Product creation is more than setting `name`, `price`, and `sku`.

MCP/AI should understand:

```text
Basic Details.
Type Options.
Trial Options.
Subscription Options.
Additional Options.
Shipping Options.
Bundle Options.
Import Products.
Third-Party Shop Download.
Product image behavior.
Bundle Product vs Bundled Products.
Unbundle methods.
```

Use the operation schema for exact request formatting, and use the overview/KB for conceptual correctness.

---

# Supported Input Fields

| Field | Type | Required | Purpose |
|---|---:|---:|---|
| `name` | string | Yes | Product name. |
| `description` | string | No | Plain text Product description. |
| `description_html` | string | No | Product description in HTML format. |
| `enabled` | boolean | No | Whether the Product is currently enabled. |
| `sku` | string | Yes | Product SKU. |
| `url` | string | No | Product URL at a third-party shop or storefront. |
| `image_url` | string | No | Direct JPG/JPEG/PNG image URL. RevCent downloads, compresses, and hosts it on the RevCent CDN. |
| `internal_id` | string | No | Internal/external Product ID. Critical for third-party shop Products. |
| `price` | number | Yes | Actual Product transaction price. |
| `price_trial` | number | No | Trial expiration price. Defaults to Product price. |
| `price_subscription` | number | No | Subscription renewal price. Defaults to Product price. |
| `trial_shipping_setting` | enum string | No | `trial_expiration`, `trial_creation`, or `both_trial_expiration_creation`. Defaults to `trial_expiration`. |
| `trial_days` | integer | No | Number of days a trial lasts after purchase. |
| `cost` | number | No | Estimated Product cost for internal tracking/reporting. |
| `is_shippable` | boolean | No | Whether the Product is shippable. |
| `shipping_attributes` | object | Conditionally | Shipping details. Required when Product is shippable. |
| `additional_id` | array<object> | No | Additional Product identifiers. |
| `third_party_shop` | string | Conditionally | 20-character third-party shop ID. Required if Product is associated with a third-party shop. |
| `subscription_profile` | string | Conditionally | 20-character Subscription Profile ID. Required if Product is a subscription Product. |
| `parent_product` | string | No | Parent Product ID or internal ID for child Products. |
| `is_bundle_product` | boolean | No | Whether the Product is a bundle of other Products. |
| `bundle_settings` | object | Conditionally | Required bundle details when Product is a bundle. |
| `product_group` | array<string> | No | Product Group IDs. |
| `google_product_category` | string | No | Google Product category ID for listings/agentic commerce. |
| `msrp` | number | No | Display-only MSRP. |
| `is_price_sale` | boolean | No | Display-only sale indicator. |
| `price_sale` | number | No | Display-only sale price. Does not affect transaction price. |
| `is_discount` | boolean | No | Display-only discount indicator. |
| `discount_rate` | number | No | Display-only discount rate. |
| `in_stock` | boolean | No | Display/listing stock indicator. |
| `stock` | integer | No | Display/listing stock quantity. |
| `brand` | string | No | Product brand. |
| `material` | string | No | Product material. |
| `age_group` | enum string | No | `adult`, `kids`, `toddler`, `infant`, or `newborn`. |
| `condition` | enum string | No | `new`, `used`, or `refurbished`. |
| `rating_value` | number | No | Rating value from 0 to 5. |
| `rating_count` | integer | No | Rating count. |
| `upc` | string | No | UPC. Recommended for agentic commerce where applicable. |
| `isbn` | string | No | ISBN. |
| `asin` | string | No | ASIN. |
| `mpn` | string | No | MPN. |
| `ean` | string | No | EAN. |

---

---

# ChatGPT Instant Checkout / ACP Product Creation Readiness

RevCent can list eligible Products for ChatGPT Instant Checkout through ACP, the Agentic Commerce Protocol.

`CreateProduct` is one of the operations used to populate the Product data that RevCent can use for agentic commerce listings. A Product existing in RevCent does not automatically mean it is ready for ChatGPT Instant Checkout. The Product must have complete and accurate listing, image, availability, category, identifier, and fulfillment data.

MCP/AI should treat ChatGPT Instant Checkout readiness as a Product creation checklist.

Important Product fields for ChatGPT Instant Checkout / ACP include:

```text
name
description or description_html
price
sku
url
image_url
enabled
in_stock
stock, if available
google_product_category
brand, when applicable
condition
upc, ean, mpn, isbn, or asin when applicable
is_shippable
shipping_attributes
shipping_attributes.fulfillment_account, if shippable
third_party_shop, if imported from a user shop
internal_id, if imported from a user shop
```

These fields help RevCent and ACP provide:

```text
Product title.
Product description.
Product detail page URL.
Product image.
Transaction price.
Availability.
Inventory signal.
Product taxonomy/category.
Brand/manufacturer context.
Product condition.
Product identifiers.
Fulfillment readiness.
```

Do not assume optional display/listing fields are unimportant. For ChatGPT Instant Checkout, fields that may be optional for normal RevCent checkout can be important or effectively required for discovery, listing quality, and checkout eligibility.

---

## ChatGPT Instant Checkout Field Mapping

| RevCent Field | Listing / ACP Meaning |
|---|---|
| `name` | Product title/name. |
| `description` / `description_html` | Product description. |
| `price` | Actual transaction price. |
| `sku` | Stable merchant Product identifier. |
| `url` | Product detail page URL. |
| `image_url` | Main Product image. Must be a direct JPG/JPEG/PNG image URL. |
| `enabled` | Product should generally be enabled to be actively listed/sold. |
| `in_stock` | Availability signal. |
| `stock` | Inventory quantity, if known. |
| `google_product_category` | Product taxonomy/category for listings and agentic commerce. |
| `brand` | Product brand/manufacturer, when applicable. |
| `condition` | Product condition: `new`, `used`, or `refurbished`. |
| `upc`, `ean`, `mpn`, `isbn`, `asin` | Product identifiers that improve matching and trust. |
| `is_shippable` | Whether the Product requires shipping. |
| `shipping_attributes` | Shipping weight/dimensions and fulfillment-account data. |
| `shipping_attributes.fulfillment_account` | Required for shippable Products. |
| `third_party_shop` | RevCent user shop ID for imported shop Products. |
| `internal_id` | External shop Product ID for imported shop Products. |

---

## ChatGPT Instant Checkout Creation Checklist

Before creating a Product intended for ChatGPT Instant Checkout, MCP/AI should verify:

1. User intends the Product to be available for ChatGPT Instant Checkout / agentic commerce.
2. `name` is clear and customer-facing.
3. `sku` is stable.
4. `price` is accurate and is the real transaction price.
5. `description` or `description_html` is useful.
6. `url` points to the Product detail page.
7. `image_url` is a direct JPG/JPEG/PNG image URL.
8. `enabled` is intentional.
9. `in_stock` reflects actual availability.
10. `stock` is populated when inventory quantity is known.
11. `google_product_category` is the most specific accurate category ID.
12. `brand` is populated when applicable.
13. `condition` is correct.
14. Product identifiers such as `upc`, `ean`, `mpn`, `isbn`, or `asin` are included when applicable and known.
15. If shippable, `is_shippable = true`.
16. If shippable, `shipping_attributes.fulfillment_account` is provided.
17. If shippable, the Fulfillment Account is enabled and correct.
18. If imported from WooCommerce or another user shop, `third_party_shop`, `internal_id`, and `sku` are correctly mapped.
19. Product data is not guessed or invented.

MCP/AI should not claim a Product will definitely appear in ChatGPT just because it was created. RevCent controls the ACP listing layer and the Product must satisfy RevCent's Instant Checkout / ACP eligibility and listing requirements.

# Product Image: `image_url`

`CreateProduct` supports `image_url` for setting the initial Product image.

When `image_url` is provided, RevCent will:

```text
Download the image.
Compress the image.
Host the image within the RevCent CDN for optimal delivery.
Make the Product image accessible through a RevCent CDN URL.
Allow the Product image to be used in Email Templates.
```

Requirements:

```text
image_url must be a direct URL to an image file.
image_url must not be a webpage URL.
Only jpg, jpeg, and png are supported.
```

Good examples:

```text
https://cdn.example.com/products/coffee-2lb.jpg
https://example.com/images/product-main.jpeg
https://images.example.com/products/starter-kit.png
```

Bad examples:

```text
https://example.com/products/coffee-2lb
https://example.com/product-page.html
https://example.com/images/product.webp
https://example.com/images/product.svg
```

If the Product is associated with a third-party shop, it is recommended to set `image_url` to the Product image from that third-party shop.

---

# Basic Details

MCP/AI should collect the Product's basic details first:

```text
name
sku
price
description
description_html
enabled
url
image_url
```

## `name`

Use a clear, descriptive Product name.

Good:

```text
Organic Coffee Beans - 2 lb Bag
Monthly Coffee Subscription
Starter Supplement Bundle
```

Poor:

```text
Product 1
Test
New Item
```

## `sku`

Use a stable SKU that can work across fulfillment, inventory, third-party shops, support, reporting, and external systems.

Examples:

```text
COFFEE-2LB
SUPP-STARTER-KIT
SUB-COFFEE-MONTHLY
```

## `price`

`price` is the actual transaction price.

Important:

```text
price is used for transactions.
price_sale is display-only and does not affect the transaction price.
```

## `enabled`

Set `enabled = true` only when the Product is ready.

Use `enabled = false` when the Product is missing:

```text
Fulfillment setup.
Subscription profile.
Bundle settings.
Third-party shop mapping.
Confirmed pricing.
Product image/content review.
```

## `url` vs `image_url`

```text
url = Product page URL.
image_url = direct image file URL.
```

Do not confuse them.

---

# Type Options

Before creating a Product, identify its type/behavior:

```text
Physical/shippable.
Digital/non-shippable.
Subscription-based.
Trial-based.
Bundle Product.
Third-party shop Product.
Parent/child Product.
```

This determines conditional fields and follow-up checks.

---

---

# Creating Products From Third-Party Shop `remote_data`

`CreateProduct` can be used as part of a Product import process from a user third-party shop.

This is especially important for WooCommerce stores.

After a user links a WooCommerce store with RevCent, MCP/AI should retrieve remote WooCommerce Products through the User Shop using `GetUserShop` and `remote_data: ["products"]`.

Important:

```text
Do not blindly create Products from remote_data.
Use the exists_in_revcent property returned in remote_data.products.
If exists_in_revcent = true, use EditProduct only if updates are needed.
If exists_in_revcent = false, use CreateProduct.
```

The `exists_in_revcent` property is the correct WooCommerce import de-duplication signal.

Do not replace this workflow with a manual SearchProducts/GetProduct duplicate search unless troubleshooting an edge case where the remote data is incomplete or ambiguous.

---

## WooCommerce Remote Product Retrieval

After the WooCommerce store is linked with RevCent, use:

```text
GetUserShop
```

with:

```json
{
  "user_shop_id": "XXXXXXXXXXXXXXXXXXXX",
  "remote_data": [
    "products"
  ]
}
```

In URL/query-parameter style transports, this may be represented as a `remote_data` URL parameter.

The important concept is:

```text
remote_data must include products.
```

`GetUserShop.remote_data` applies to WooCommerce stores and can retrieve remote shop Products that:

- exist in the remote shop but have not been created in RevCent,
- already exist in RevCent,
- were updated remotely and may need to be updated in RevCent.

Known `remote_data` options include:

```text
products
shipping_methods
offline_payment_methods
```

For Product import, use:

```text
products
```

---

## Correct Duplicate-Prevention Workflow: Use `exists_in_revcent`

Before creating any Product from WooCommerce / third-party shop `remote_data.products`, MCP/AI must check the returned:

```text
exists_in_revcent
```

property.

Decision rule:

| `exists_in_revcent` | Correct Action |
|---:|---|
| `false` | Use `CreateProduct`. |
| `true` | Do not create a duplicate. Use `EditProduct` only if updates are needed. |

This property is already provided in the remote product retrieval workflow and should be used to prevent duplication.

Correct workflow:

```text
1. Call GetUserShop with remote_data: ["products"].
2. Review each item in remote_data.products.
3. For each remote Product:
       If exists_in_revcent = false:
           prepare CreateProduct.
       If exists_in_revcent = true:
           use EditProduct only if updates are needed.
4. Preserve internal_id from the remote shop Product ID.
5. Set third_party_shop to the RevCent User Shop ID.
6. Configure shippable, fulfillment, subscription, trial, Product Group, image, listing, and pricing fields as needed.
7. Confirm with the user before creating/updating Products.
8. Run CreateProduct/EditProduct.
9. Verify imported/updated Products.
```

---

## Why `exists_in_revcent` Is Preferred

The `exists_in_revcent` field is preferred because RevCent's User Shop remote data workflow already determines whether a remote shop Product has a corresponding RevCent Product.

This is better than forcing an AI/MCP client to manually infer duplicates from search results.

Older manual duplicate-prevention methods can be fragile because:

- Product name is not reliable.
- SKU may be reused across shops.
- SKU may be missing or changed.
- Search results may include unrelated Products.
- Internal IDs are only meaningful in the context of the shop.
- Multiple shops can have similar or identical Product catalogs.
- Search-based matching can create false positives or false negatives.

The correct WooCommerce import flow is:

```text
GetUserShop remote_data: ["products"]
    ↓
Use exists_in_revcent
    ↓
CreateProduct only when exists_in_revcent = false
    ↓
EditProduct only when exists_in_revcent = true and updates are needed
```

---

## Product Import Identity Fields

Even though `exists_in_revcent` should be used for de-duplication, MCP/AI must still preserve Product identity fields when creating or editing imported Products.

Critical mapping:

```text
third_party_shop = RevCent User Shop ID
internal_id = remote shop Product ID
```

For WooCommerce Products:

```text
internal_id should be the WooCommerce Product ID.
third_party_shop should be the RevCent User Shop ID.
```

This mapping allows RevCent to reliably connect the WooCommerce Product to the RevCent Product across future imports, Sales, Product Sales, subscriptions, trials, shipments, refunds, emails, AI workflows, and reporting.

---

## Remote Product Field Awareness

Remote Products returned through `GetUserShop remote_data: ["products"]` can include fields used for Product import decisions.

Important fields include:

| Field | Meaning |
|---|---|
| `exists_in_revcent` | Whether the remote Product already exists in RevCent. Use this to prevent duplicates. |
| `id` | RevCent Product ID when the Product already exists in RevCent. Use for `EditProduct` when available. |
| `internal_id` | Remote shop Product ID. Preserve this as `internal_id`. |
| `sku` | Remote Product SKU. Preserve where available. |
| `name` | Product name. |
| `image_url` | Product image URL. |
| `url` | Remote Product page URL. |
| `description` / `description_html` | Product description content where available. |
| `is_shippable` | Whether the remote Product requires shipping. |
| Pricing/status fields | Used to configure RevCent Product behavior where applicable. |

The exact fields may vary by shop and response, but the AI/MCP client must treat `exists_in_revcent` as the primary create-vs-edit signal when importing from WooCommerce remote data.

---

## Create vs Edit Decision Table

| Remote Product State | Correct Operation |
|---|---|
| `exists_in_revcent = false` | `CreateProduct` |
| `exists_in_revcent = true` and remote Product has a RevCent Product `id` | `EditProduct` only if updates are needed |
| `exists_in_revcent = true` and no changes are needed | No Product operation needed |
| Product exists remotely but mapping looks incomplete | Investigate before creating; do not blindly create a duplicate |
| Remote Product is shippable | Configure `is_shippable` and `shipping_attributes.fulfillment_account` |
| Remote Product has subscription behavior | Configure RevCent subscription settings only |
| Remote Product has trial behavior | Configure RevCent trial settings |

---

## WooCommerce Product to RevCent Product Mapping

When importing a WooCommerce Product, MCP/AI should map WooCommerce data into `CreateProduct` or `EditProduct` fields.

Recommended mapping:

| WooCommerce Data | RevCent Product Field |
|---|---|
| WooCommerce Product ID | `internal_id` |
| WooCommerce Product name | `name` |
| WooCommerce SKU | `sku` |
| WooCommerce price | `price` |
| WooCommerce short/long description | `description` / `description_html` |
| WooCommerce Product permalink | `url` |
| WooCommerce main image URL | `image_url` |
| WooCommerce stock status | `in_stock` |
| WooCommerce stock quantity | `stock` |
| WooCommerce brand/category attributes | `brand`, `google_product_category`, `product_group`, or metadata when appropriate |
| WooCommerce weight/dimensions | `shipping_attributes.weight`, `length`, `width`, `height` |
| RevCent User Shop ID | `third_party_shop` |
| Fulfillment routing | `shipping_attributes.fulfillment_account` |

Important:

```text
For WooCommerce Products, internal_id should be the WooCommerce Product ID.
For WooCommerce Products, third_party_shop should be the RevCent User Shop ID.
For WooCommerce Products, image_url should be the direct WooCommerce Product image URL.
```

---

## WooCommerce Import CreateProduct Example

Example `CreateProduct` request when `exists_in_revcent = false`:

```json
{
  "name": "Organic Coffee Beans - 2 lb Bag",
  "sku": "COFFEE-2LB",
  "price": 29.99,
  "description": "Organic medium roast coffee beans.",
  "description_html": "<p>Organic medium roast coffee beans with notes of chocolate and citrus.</p>",
  "url": "https://example-store.com/product/organic-coffee-beans-2lb",
  "image_url": "https://example-store.com/wp-content/uploads/coffee-2lb.jpg",
  "third_party_shop": "SSSSSSSSSSSSSSSSSSSS",
  "internal_id": "12345",
  "enabled": true,
  "in_stock": true,
  "stock": 48,
  "brand": "Example Brand",
  "condition": "new"
}
```

If the Product is shippable, add:

```json
{
  "is_shippable": true,
  "shipping_attributes": {
    "weight": "2",
    "length": "10",
    "width": "7",
    "height": "4",
    "fulfillment_account": "FFFFFFFFFFFFFFFFFFFF"
  }
}
```

---

## WooCommerce Import EditProduct Example

Example `EditProduct` request when `exists_in_revcent = true` and the returned remote Product has an existing RevCent Product ID:

```json
{
  "product_id": "PPPPPPPPPPPPPPPPPPPP",
  "name": "Updated Product Name",
  "sku": "UPDATED-SKU",
  "internal_id": "12345",
  "third_party_shop": "SSSSSSSSSSSSSSSSSSSS",
  "url": "https://example-store.com/product/updated-product",
  "image_url": "https://example-store.com/wp-content/uploads/updated-product.jpg"
}
```

Only send fields that should be updated.

Do not edit a Product just because it exists. Edit only when remote data or required RevCent configuration needs to be updated.

---

## WooCommerce Import Review Checklist

Before creating or editing a WooCommerce remote Product in RevCent:

1. WooCommerce store is linked to RevCent.
2. Correct User Shop was identified.
3. `GetUserShop` was called with `remote_data: ["products"]`.
4. Remote Products were reviewed.
5. `exists_in_revcent` was checked for every Product.
6. If `exists_in_revcent = true`, `CreateProduct` is not used.
7. If `exists_in_revcent = true`, `EditProduct` is used only if updates are needed.
8. If `exists_in_revcent = false`, `CreateProduct` may be used.
9. `internal_id` is set to the WooCommerce Product ID.
10. `third_party_shop` is set to the RevCent User Shop ID.
11. SKU/name/price/url/image data are accurate.
12. `image_url` is a direct JPG/JPEG/PNG image URL.
13. Shippable Products have a Fulfillment Account.
14. Subscription Products use RevCent subscription settings only.
15. Trial Products use RevCent trial settings.
16. Product Group assignment is considered.
17. Instant Checkout/listing fields are populated when needed.
18. No guessed Product identifiers or category values are used.

---

## Do Not Create Duplicates

Duplicate Product creation creates operational problems.

Potential issues:

```text
Two RevCent Products mapped to the same WooCommerce Product.
Incorrect Product Sales mapping.
Wrong Product appearing in reports.
Fulfillment confusion.
Duplicate Product listings.
Incorrect ChatGPT Instant Checkout / ACP listing behavior.
Customer support confusion.
Incorrect Product image or price updates.
```

The safest rule:

```text
For WooCommerce/user shop imports, use GetUserShop remote_data: ["products"] and rely on exists_in_revcent before CreateProduct.
```

If `exists_in_revcent = true`, use:

```text
EditProduct
```

only if updates are needed.

Do not use:

```text
CreateProduct
```

for a remote Product that already exists in RevCent.


# Third-Party Shop Products

Important WooCommerce import rule:

```text
Use GetUserShop remote_data: ["products"] and the returned exists_in_revcent value to decide create vs edit.
```

If the Product is associated with a third-party shop:

```text
third_party_shop is required.
internal_id is extremely important.
```

Recommended mapping:

```text
third_party_shop = RevCent third-party shop ID
internal_id = external shop Product ID
url = external Product page URL
image_url = direct external shop Product image URL
sku = stable Product SKU
```

Example:

```json
{
  "name": "Organic Coffee Beans - 2 lb Bag",
  "price": 29.99,
  "sku": "COFFEE-2LB",
  "third_party_shop": "SSSSSSSSSSSSSSSSSSSS",
  "internal_id": "woocommerce_product_12345",
  "url": "https://example.com/products/coffee-2lb",
  "image_url": "https://example.com/wp-content/uploads/coffee-2lb.jpg"
}
```

Do not invent `internal_id`. Use the source shop's Product ID.

---

# Shipping Options

A shippable Product should include:

```text
is_shippable = true
shipping_attributes.fulfillment_account
```

The schema states `shipping_attributes.fulfillment_account` is required if the Product is shippable.

`shipping_attributes` fields:

| Field | Unit | Purpose |
|---|---:|---|
| `weight` | pounds | Product weight. |
| `length` | inches | Product length. |
| `width` | inches | Product width. |
| `height` | inches | Product height. |
| `fulfillment_account` | ID | 20-character Fulfillment Account ID. |

Example:

```json
{
  "name": "Organic Coffee Beans - 2 lb Bag",
  "price": 29.99,
  "sku": "COFFEE-2LB",
  "is_shippable": true,
  "shipping_attributes": {
    "weight": "2",
    "length": "10",
    "width": "7",
    "height": "4",
    "fulfillment_account": "FFFFFFFFFFFFFFFFFFFF"
  }
}
```

MCP/AI should use `GetFulfillmentAccounts` to retrieve available Fulfillment Accounts.

Important:

```text
If a Product is shippable and the attached Fulfillment Account is disabled, the Product may not ship.
```

---

# Subscription Options

A subscription Product requires:

```text
subscription_profile
```

Use `GetSubscriptionProfiles` to retrieve available Subscription Profiles.

Use `price_subscription` when renewal price differs from the initial Product price.

Example:

```json
{
  "name": "Monthly Coffee Subscription",
  "price": 19.99,
  "price_subscription": 29.99,
  "sku": "COFFEE-SUB-MONTHLY",
  "subscription_profile": "PPPPPPPPPPPPPPPPPPPP"
}
```

Do not create a subscription Product without a valid Subscription Profile.

---

# Trial Options

Trial fields:

```text
trial_days
price_trial
trial_shipping_setting
```

Allowed `trial_shipping_setting` values:

```text
trial_expiration
trial_creation
both_trial_expiration_creation
```

Default:

```text
trial_expiration
```

Example:

```json
{
  "name": "14-Day Starter Trial Kit",
  "price": 0,
  "sku": "TRIAL-KIT-14D",
  "trial_days": 14,
  "price_trial": 49.99,
  "trial_shipping_setting": "trial_creation"
}
```

If the trial Product is shippable, also include `is_shippable` and `shipping_attributes.fulfillment_account`.

---

# Bundle Options

A bundle Product uses:

```text
is_bundle_product = true
bundle_settings
```

The Product Bundle KB distinguishes:

```text
Bundle Product = the Product being sold as the bundle.
Bundled Products = the component Products inside the bundle.
```

`bundle_settings` contains:

```text
products
unbundle_method
```

Each bundled Product has:

```text
id
quantity
price
```

Allowed `unbundle_method` values:

```text
unbundle_at_fulfillment
unbundle_at_sale
```

Example:

```json
{
  "name": "Starter Bundle",
  "price": 75.00,
  "sku": "BUNDLE-STARTER",
  "is_bundle_product": true,
  "bundle_settings": {
    "products": [
      {
        "id": "AAAAAAAAAAAAAAAAAAAA",
        "quantity": 1,
        "price": 25.00
      },
      {
        "id": "BBBBBBBBBBBBBBBBBBBB",
        "quantity": 2,
        "price": 25.00
      }
    ],
    "unbundle_method": "unbundle_at_fulfillment"
  }
}
```

Bundle allocated total:

```text
Product A: 1 × $25 = $25
Product B: 2 × $25 = $50
Total = $75
```

MCP/AI should verify:

```text
Sum of component allocated prices equals bundle Product price.
```

This matters for Product Sales, revenue reporting, refund allocation, fulfillment, customer communication, and event data.

---

# Bundle Unbundle Method

## `unbundle_at_sale`

Use when the bundle should decompose into component Product Sales at sale time.

Good for:

```text
Immediate component-level reporting.
Component-level refunds.
Automation that needs component Product Sales immediately.
```

## `unbundle_at_fulfillment`

Use when the bundle should decompose for fulfillment.

Good for:

```text
Physical kits.
Warehouse picking.
Customer-facing bundle with component fulfillment.
```

MCP/AI should not guess this value. Confirm how the business wants sale records, fulfillment, reporting, customer communication, and event data to behave.

---

# Subscription and Trial Bundle Products

A Product can be both a bundle and a subscription/trial Product when the business model requires it.

Before creating a subscription or trial bundle, verify:

```text
is_bundle_product
bundle_settings.products
bundle_settings.unbundle_method
price
component price allocation
subscription_profile, if subscription Product
price_subscription, if renewal price differs
trial_days, if trial Product
price_trial, if trial expiration price differs
trial_shipping_setting, if trial shipping matters
is_shippable
shipping_attributes.fulfillment_account
component Product fulfillment requirements
image_url, if customer-facing
```

Do not configure subscription/trial bundles by assumption.

---

# Additional Options

## `cost`

Internal estimated Product cost for tracking/reporting.

## `additional_id`

Use for external identifiers.

Example:

```json
{
  "additional_id": [
    {
      "name": "warehouse_sku",
      "value": "WH-12345"
    },
    {
      "name": "supplier_id",
      "value": "SUP-9988"
    }
  ]
}
```

Use cases:

```text
Warehouse SKU.
ERP ID.
Supplier Product ID.
Marketplace listing ID.
Legacy Product ID.
External fulfillment item ID.
```

## `parent_product`

Use when creating a child/variant Product.

`parent_product` can be:

```text
The internal_id of an existing Product.
A 20-character RevCent Product ID.
```

---

# Product Groups

Use `product_group` to place a Product into Product Groups.

Example:

```json
{
  "product_group": [
    "GGGGGGGGGGGGGGGGGGGG"
  ]
}
```

Product Groups can support:

```text
Reporting.
Filters.
Payment routing.
Promotions.
Shipping logic.
Product organization.
AI analysis.
Customer support segmentation.
```

MCP/AI should retrieve or confirm Product Group IDs before assigning them.

---

# Display and Listing Fields

Display/listing fields include:

```text
google_product_category
msrp
is_price_sale
price_sale
is_discount
discount_rate
in_stock
stock
brand
material
age_group
condition
rating_value
rating_count
upc
isbn
asin
mpn
ean
image_url
```

Important:

```text
price_sale is display-only.
price determines the actual transaction price.
```

`google_product_category` is used for Product listings including agentic commerce such as ChatGPT Instant Checkout. Use the most specific accurate category ID.

Allowed `age_group` values:

```text
adult
kids
toddler
infant
newborn
```

Allowed `condition` values:

```text
new
used
refurbished
```

Do not invent UPC/EAN/MPN/ISBN/ASIN/category/rating values.

---

# Import Product Awareness

The Product KB includes Product import workflows.

If the user wants to create many Products, an import workflow may be more appropriate than calling `CreateProduct` repeatedly.

MCP/AI should understand:

```text
CSV imports can create/update multiple Products.
Third-party shop downloads can import Products from a connected shop.
Imported Products may still need review for fulfillment, subscription profiles, bundle settings, images, and shop mapping.
Import success/error/complete results should be reviewed.
```

Do not assume imported Products are ready to sell without review.

---

# Output Schema

Successful response can include:

```json
{
  "api_call_id": "XXXXXXXXXXXXXXXXXXXX",
  "api_call_unix": 1770000000,
  "code": 1,
  "product_id": "YYYYYYYYYYYYYYYYYYYY",
  "result": "..."
}
```

MCP/AI should return or save the `product_id`.

---

# Validation Checklist

Before calling `CreateProduct`:

1. Product does not already exist.
2. `name` is known and descriptive.
3. `price` is known and intentional.
4. `sku` is known and stable.
5. `enabled` is intentional.
6. `image_url`, if provided, is a direct JPG/JPEG/PNG image URL.
7. Product page `url`, if provided, is not confused with `image_url`.
8. If third-party shop Product, `third_party_shop` is provided.
9. If third-party shop Product, `internal_id` is the external shop Product ID.
10. If shippable, `is_shippable = true`.
11. If shippable, `shipping_attributes.fulfillment_account` is provided.
12. Fulfillment Account is enabled and correct.
13. If subscription Product, `subscription_profile` is provided.
14. If trial Product, `trial_days`, `price_trial`, and `trial_shipping_setting` are intentional.
15. If bundle Product, component IDs, quantities, prices, and unbundle method are intentional.
16. Bundle component allocated total equals Product `price`.
17. Product Group IDs are valid if provided.
18. Display/listing identifiers and category values are accurate.
19. No unsupported fields are sent.
20. No guessed prices, IDs, images, weights, dimensions, ratings, or category IDs are included.
21. If importing from a user shop, `GetUserShop` was called with `remote_data: ["products"]` and the remote Product's `exists_in_revcent` property was checked before creating.

---

# Common Mistakes


## Mistake: Creating Duplicate Products From User Shop Remote Data

Wrong:

```text
Create every Product returned by GetUserShop remote_data: ["products"] without checking exists_in_revcent.
```

Correct:

```text
Use the exists_in_revcent property returned in remote_data.products.
If exists_in_revcent = true, do not use CreateProduct.
If exists_in_revcent = false, use CreateProduct and preserve internal_id + third_party_shop.
```


## Mistake: Webpage URL as `image_url`

Wrong:

```text
https://example.com/products/coffee-2lb
```

Correct:

```text
https://example.com/images/coffee-2lb.jpg
```

## Mistake: Shippable Product Without Fulfillment Account

Wrong:

```json
{
  "name": "Physical Product",
  "price": 29.99,
  "sku": "PHYS-001",
  "is_shippable": true
}
```

Correct:

```json
{
  "name": "Physical Product",
  "price": 29.99,
  "sku": "PHYS-001",
  "is_shippable": true,
  "shipping_attributes": {
    "fulfillment_account": "FFFFFFFFFFFFFFFFFFFF"
  }
}
```

## Mistake: Subscription Product Without Subscription Profile

Wrong:

```text
Create recurring Product but omit subscription_profile.
```

Correct:

```text
Attach a valid subscription_profile.
```

## Mistake: Bundle Total Does Not Equal Product Price

Wrong:

```text
Bundle Product price = $100
Component allocated total = $80
```

Correct:

```text
Bundle Product price = $100
Component allocated total = $100
```

## Mistake: Display Sale Price Confusion

Wrong:

```text
Set price_sale and assume checkout amount changed.
```

Correct:

```text
Set price for actual transaction price. price_sale is display-only.
```

---

# Key Takeaways

```text
CreateProduct creates a new Product.
```

```text
For WooCommerce/user shop imports, call `GetUserShop` with `remote_data: ["products"]` and use `exists_in_revcent` before calling CreateProduct.
```

```text
CreateProduct requires name, price, and sku.
```

```text
image_url must be a direct JPG/JPEG/PNG image URL.
```

```text
RevCent downloads, compresses, and hosts Product images on the RevCent CDN.
```

```text
Shippable Products require a Fulfillment Account.
```

```text
Subscription Products require a Subscription Profile.
```

```text
Third-party shop Products require correct third_party_shop and internal_id mapping.
```

```text
Bundle Products require valid bundle_settings and intentional unbundle method.
```

```text
Bundle component totals should equal the bundle Product price.
```

```text
price is the actual transaction price; price_sale is display-only.
```

```text
Read the Products overview and Product KB before creating complex Products:
https://revcent.com/documentation/markdown/mcp/operation/OverviewProduct.md
https://kb.revcent.com/en/product
https://kb.revcent.com/product/product-bundle
```


---
Document Parent Directory
* [Operations](https://revcent.com/documentation/markdown/mcp/operation/index.md) - AI/MCP details and overviews for operations available within the RevCent MCP.