# Product content and recommendations (/ai/reference/catalog/product-content)

Toolset `product_content`, 9 tools.

## Records [#records]

### `product_relations` [#product_relations]

The related products and add-ons one product shows: the ones picked by hand, the ones picked automatically and the automatic ones hidden. Pass the product id.

- Permission: `products.read`
- Tools: `product_relations_get`

### `recommendation_excluded` [#recommendation_excluded]

The products the store never recommends, with their title and thumbnail.

- Permission: `products.read`
- Tools: `recommendation_excluded_list`

### `recommendation_settings` [#recommendation_settings]

How the store recommends products: whether it is on, where it shows (product page related and add-ons, cart, abandoned-cart email), the categories it leaves out, the price band of a similar product and the signals it uses. There is one record; pass any id, e.g. "current".

- Permission: `products.read`
- Tools: `recommendation_settings_get`

### `variants_without_weight` [#variants_without_weight]

How many variants have no weight, which weight-based shipping prices cannot use. There is one record; pass any id, e.g. "current".

- Permission: `products.read`
- Tools: `variants_without_weight_get`

## Actions [#actions]

### `product_relations_hide_auto` [#product_relations_hide_auto]

Hide or show one automatically chosen related product or add-on on a product.

- Action key: `product_relations.hide_auto`
- Permission: `products.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | string | yes |  |
| `kind` | string | yes | one of "related", "addon" |
| `other_product_id` | string | yes | The recommended product to hide or show |
| `hidden` | boolean | yes |  |

Example input:

```json
{
  "product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
  "kind": "related",
  "other_product_id": "019bb596-4f49-7df2-8e43-087dbab6350c",
  "hidden": true
}
```

### `product_relations_set` [#product_relations_set]

Add related products or add-ons to a product, or unlink them.

kind is related or addon. product_ids are added to the hand-picked list, or taken off it with unlink. mutual links both products to each other.

- Action key: `product_relations.set`
- Permission: `products.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | string | yes |  |
| `kind` | string | yes | one of "related", "addon" |
| `product_ids` | list of string | yes | at least 1 characters |
| `mutual` | boolean |  |  |
| `unlink` | boolean |  |  |

Example input:

```json
{
  "product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
  "kind": "related",
  "product_ids": [
    "019bb596-4f49-7df2-8e43-087dbab6350c"
  ]
}
```

### `product_seo_set` [#product_seo_set]

Set the search title and description of a product, its share card, and how search engines index it.

Read the current settings with product_get include seo. A field left out stays as it is; null resets it to automatic. robots_index false hides the page from search engines and the sitemap; canonical_url names the address search engines should index instead (a storefront path /… or an https address). The sitemap priority and change frequency are hints search engines mostly ignore; leave them automatic unless asked.

- Action key: `product_seo.set`
- Permission: `products.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | string | yes |  |
| `seo_title` | string or null |  | Search result title; null resets it. at most 70 characters |
| `seo_description` | string or null |  | Search result description; null resets it. at most 320 characters |
| `og_title` | string or null |  | Title of the share card on social networks; null uses the search title. at most 200 characters |
| `og_description` | string or null |  | Text of the share card; null uses the search description. at most 500 characters |
| `og_media_id` | string or null |  | Media library file id of the share picture (media_list finds them); null removes it |
| `robots_index` | boolean |  | false hides the page from search engines |
| `robots_follow` | boolean |  | false asks search engines not to follow the links on the page |
| `canonical_url` | string or null |  | The address search engines index instead; null clears it. at most 2048 characters |
| `sitemap_include` | boolean |  | false leaves the page out of the sitemap |
| `sitemap_priority` | number or null |  | 0 to 1 in steps of 0.1; null is automatic. 0 to 1 |
| `sitemap_changefreq` | string or null |  | null is automatic. one of "always", "hourly", "daily", "weekly", "monthly", "yearly", "never" |
| `search_expires_at` | string or null |  | ISO 8601 date and time after which search engines drop the page; null clears it |

Example inputs:

```json
{
  "product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
  "seo_title": "Handmade soap",
  "seo_description": "Cold-process soap."
}
```

```json
{
  "product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
  "og_title": "Our handmade soap",
  "robots_index": false
}
```

### `recommendation_rule_set` [#recommendation_rule_set]

Turn automatic recommendations off for a product, or leave it out of everyone else's.

- Action key: `recommendation_rule.set`
- Permission: `products.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | string | yes |  |
| `auto_off` | boolean |  | No automatic recommendations on this product page |
| `excluded` | boolean |  | Never recommend this product |

Example input:

```json
{
  "product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
  "excluded": true
}
```

### `recommendation_settings_update` [#recommendation_settings_update]

Change how products are recommended.

Only the fields passed change.

- Action key: `recommendation_settings.update`
- Permission: `settings.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `enabled` | boolean |  |  |
| `placements` | object |  |  |
| `placements.pdp_related` | boolean |  |  |
| `placements.pdp_addons` | boolean |  |  |
| `placements.cart` | boolean |  |  |
| `placements.abandoned_cart_email` | boolean |  |  |
| `excluded_category_ids` | list of string |  | at most 200 items |
| `similar_price_band` | number |  | 0.5 keeps prices within half to one and a half times. 0.1 to 5 |
| `signals` | object |  |  |
| `signals.bought` | boolean |  |  |
| `signals.viewed` | boolean |  |  |
| `signals.similar` | boolean |  |  |

Example input:

```json
{
  "enabled": true,
  "placements": {
    "cart": false
  }
}
```
