Elastic Path Product Relationships API
The Product Relationships API from Elastic Path — 3 operation(s) for product relationships.
The Product Relationships API from Elastic Path — 3 operation(s) for product relationships.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/elastic-path-product-relationships-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Product Experience Manager Introduction Product Relationships API
description: '
Product Experience Manager uses the PIM service to manage product information, hierarchies, and price books. Ideally, Product Experience Manager becomes the single source of truth for product data across your organization.
In Commerce, the product data is stored separately from pricing, catalogs, and inventory. This separation means that you retrieve all product data only when you are managing product data and assets. Otherwise, when setting prices or managing inventory, you retrieve a reference to the product rather than the entire product, which makes the response times very fast.
You also have the flexibility to create catalogs for different scenarios by combining hierarchies of products with a price book. Scenarios might include:
- **Multiple geographical regions**. Display different catalogs in different regions with suitable pricing or combine product hierarchies from two different regions to display in a third region.
- **Multiple channels**. Display different catalogs based on how a shopper accesses your store, such as through a mobile app or a web storefront.
- **Direct to business versus direct to customers**. Offer different products and prices for business customers versus retail customers.
- **Preferred customers**. Offer special pricing to preferred customers while displaying a standard price catalog to all other shoppers.
- **Reward programs**. Enable reward programs where catalog prices drop after a certain spending level is reached.
- **Product sales**. Offer sale items for a limited time.
Scenarios are created by defining the context within which a catalog is displays. Contexts can be a customer ID, a channel, or any other user-defined tag that can be passed to the APIs from the front-end shopper experiences.
'
version: 26.0612.7739142
x-version-timestamp: 2026-06-12 10:52:50+00:00
servers:
- url: https://euwest.api.elasticpath.com
description: EU West Production Server
- url: https://useast.api.elasticpath.com
description: US East Production Server
security:
- bearerAuth: []
tags:
- name: Product Relationships
paths:
/pcm/products/{productID}/custom-relationships:
post:
parameters:
- $ref: '#/components/parameters/product_id'
summary: Attach Custom Relationships to a Product
description: "You can attach up to 5 custom relationships to a product. \n\nOnce you have attached a custom relationship to a product, you can then create relationships from a product to one or many other products. See [Associate a product to one or more products using a custom relationship](/docs/api/pxm/products/product-association-id). \n\nSee [Custom Relationships](/guides/key-concepts/product-experience-manager/custom-relationships/).\n\n### Prerequisites\n - A Custom Relationship has been created, see [create a Custom Relationship](/docs/api/pxm/products/create-custom-relationship),\n - A Product has been created.\n"
operationId: attachCustomRelationships
tags:
- Product Relationships
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/attach_custom_relationship_request'
examples:
assign-custom-relationships-to-product:
summary: attach custom relationships to product
$ref: '#/components/examples/attach_custom_relationship_request'
responses:
'201':
description: Returns the attached custom relationships
content:
application/json:
schema:
$ref: '#/components/schemas/multi_custom_relationships'
examples:
custom-relationship:
summary: Attached custom relationships
$ref: '#/components/examples/resp_multi_custom_relationships'
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
delete:
parameters:
- $ref: '#/components/parameters/product_id'
summary: Delete Custom Relationships from a Product
description: 'Delete Custom Relationships from a Product. Multiple Custom Relationships can be deleted from a product in one request.
'
operationId: detachCustomRelationships
tags:
- Product Relationships
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/attach_custom_relationship_request'
examples:
assign-custom-relationship-to-product:
$ref: '#/components/examples/attach_custom_relationship_request'
responses:
'204':
description: Successfully deleted custom relationships.
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
get:
parameters:
- $ref: '#/components/parameters/product_id'
- $ref: '#/components/parameters/page_offset'
- $ref: '#/components/parameters/page_limit'
summary: Get all Custom Relationships attached to a Product
description: "### Prerequisites\n - Custom Relationships have been attached to a product, see [Attach Custom Relationships to a Product](/docs/api/pxm/products/attach-custom-relationships)\n - **OR** Products have been related to one another, see [Create a Relationship between a product with one or more products](/docs/api/pxm/products/product-association-id)\n"
operationId: listAttachedCustomRelationship
tags:
- Product Relationships
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/attach_custom_relationship_request'
examples:
assign-custom-relationship-to-product:
$ref: '#/components/examples/attach_custom_relationship_request'
responses:
'200':
description: Returns the attached custom relationship.
content:
application/json:
schema:
$ref: '#/components/schemas/multi_custom_relationships'
examples:
custom-relationship:
$ref: '#/components/examples/resp_multi_custom_relationships'
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
/pcm/products/{productID}/custom-relationships/{customRelationshipSlug}:
post:
parameters:
- $ref: '#/components/parameters/product_id'
- $ref: '#/components/parameters/custom_relationship_slug'
summary: Create a Relationship between a Product with one or more Products
description: "- You can associate a product with up to 2000 other products. \n- You do not need to attach a custom relationship to products beforehand, this will be done automatically by this endpoint. \n- This is a partial update, so if you make a request to this endpoint multiple times with different products in each request, they will not be overwritten but will be appended to the related products list. \n\nIf you want to remove a relationship between products, see [Delete a Relationship between a product with one or more products](/docs/api/pxm/products/dissociate-products). \n\n ### Prerequisites\n - A Custom Relationship has been created, see [create a Custom Relationship](/docs/api/pxm/products/create-custom-relationship).\n - A Product has been created for the relationship to be based from.\n - One or many Product have been created for the product to relate to.\n"
operationId: productAssociationId
tags:
- Product Relationships
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/product_association_request'
examples:
create-product-association:
$ref: '#/components/examples/create_product_association_request'
responses:
'201':
description: Returns information related to associated products.
content:
application/json:
schema:
$ref: '#/components/schemas/product_association_response'
examples:
create-product-association:
$ref: '#/components/examples/create_product_association_created_response'
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
delete:
parameters:
- $ref: '#/components/parameters/product_id'
- $ref: '#/components/parameters/custom_relationship_slug'
summary: Delete a Relationship between a product with one or more products
operationId: dissociateProducts
tags:
- Product Relationships
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/product_association_delete_request'
examples:
delete-product-association:
$ref: '#/components/examples/delete_product_association_request'
responses:
'204':
description: Products are dissociated.
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
get:
summary: Get all Related Product IDs of a Products' attached Custom Relationship
description: "### Prerequisites\n - Relationships have been created between Products, see [Create a Relationship between a product with one or more products](/docs/api/pxm/products/product-association-id).\n"
operationId: getRelatedProductIDsOfAProductId
tags:
- Product Relationships
parameters:
- $ref: '#/components/parameters/page_offset'
- $ref: '#/components/parameters/page_limit'
- $ref: '#/components/parameters/product_id'
- $ref: '#/components/parameters/custom_relationship_slug'
responses:
'200':
description: Returns all related product ids.
content:
application/json:
schema:
$ref: '#/components/schemas/product_association_list_product_ids_response'
examples:
list-product-association-product-ids:
$ref: '#/components/examples/list_product_association_product_ids_response'
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'409':
$ref: '#/components/responses/write_conflict'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
/pcm/products/{productID}/custom-relationships/{customRelationshipSlug}/products:
get:
summary: Get all Related Products of a Products' attached Custom Relationship
operationId: getRelatedProductsOfAProductId
description: "### Prerequisites\n - Relationships have been created between Products, see [Create a Relationship between a product with one or more products](/docs/api/pxm/products/product-association-id).\n"
tags:
- Product Relationships
parameters:
- $ref: '#/components/parameters/page_offset'
- $ref: '#/components/parameters/page_limit'
- $ref: '#/components/parameters/product_id'
- $ref: '#/components/parameters/custom_relationship_slug'
responses:
'200':
description: Returns all related products.
content:
application/json:
schema:
$ref: '#/components/schemas/multi_product_response'
examples:
list-products:
$ref: '#/components/examples/multi_product_response'
'400':
$ref: '#/components/responses/bad_request'
'403':
$ref: '#/components/responses/forbidden'
'404':
$ref: '#/components/responses/not_found'
'422':
$ref: '#/components/responses/unprocessable_entity'
'500':
$ref: '#/components/responses/internal'
components:
parameters:
page_offset:
name: page[offset]
in: query
description: The number of records to offset the results by.
schema:
type: integer
minimum: 0
maximum: 10000
format: int64
example: 0
custom_relationship_slug:
name: customRelationshipSlug
in: path
schema:
type: string
example: CRP_electric_devices_2024
required: true
description: A custom relationship slug.
product_id:
name: productID
in: path
schema:
type: string
example: 00000000-0000-0000-0000-000000000000
x-postman-example: '{{productID}}'
required: true
description: A unique identifier for the product.
page_limit:
name: page[limit]
in: query
description: The number of records per page. The maximum limit is 100.
schema:
type: integer
minimum: 0
maximum: 10000
format: int64
example: 10
schemas:
elastic_path_file:
type: object
title: ElasticPathFile
properties:
id:
type: string
description: The unique identifier for this file.
format: uuid
type:
description: The type represents the object being returned.
type: string
example: file
file_name:
description: The name of the file.
type: string
example: file_name.jpg
mime_type:
description: The mime type of the file.
type: string
example: image/jpeg
file_size:
description: The size of the file. Required when uploading files.
type: integer
example: 36000
public:
description: DEPRECATED Whether the file public or not. Required when uploading files.
type: boolean
example: true
meta:
properties:
timestamps:
type: object
description: The date and time the file was created.
properties:
created_at:
description: The date and time the file was created.
type: string
example: '2023-10-11T13:02:25.293Z'
dimensions:
description: The file dimensions.
type: object
properties:
width:
description: The width of the file.
type: integer
example: 1800
height:
description: The height of the file.
type: integer
example: 1000
links:
description: Links are used to allow you to move between requests.
type: object
properties:
self:
description: Single entities use a self parameter with a link to that specific resource.
type: string
example: https://useast.api.elasticpath.com/v2/files/ddc28c74-a7df-46be-b262-8fa69a6e7d52
link:
type: object
description: The publicly available URL for this file.
properties:
href:
description: The publicly available URL for this file.
type: string
example: https://files-eu.epusercontent.com/e8c53cb0-120d-4ea5-8941-ce74dec06038/f8cf26b3-6d38-4275-937a-624a83994702.png
meta:
type: object
properties:
results:
description: Contains the results for the entire collection.
type: object
properties:
total:
description: Total number of results for the entire collection.
type: integer
example: 2
admin_attributes:
type: object
description: "`admin_attributes` are not displayed in catalogs. This means `admin_attributes` can only be viewed by administrators. If you want a custom attribute to be displayed in a catalog, you must add it to `shopper_attributes`. \n\n`admin_attributes` are structured as key-value pairs. Both the keys and values are `strings`. You can have up to 100 keys.\n"
example:
cost_of_goods: '42.0'
charge_type: credit card
additionalProperties:
type:
- string
- 'null'
multi_links:
type: object
description: 'Links allow you to navigate between pages of results.
:::caution Planned pagination changes — on or after 1 September 2026
The pagination behaviour of PIM list endpoints (for example, `GET /pcm/products` and `GET /pcm/hierarchies`) currently differs from the rest of the Elastic Path Commerce Cloud platform. We plan to align PIM pagination with the platform standard on or after **1 September 2026**. Please review the details below and check that your integration code will handle the new behaviour correctly.
:::
#### Current behaviour
The current pagination link behaviour in PIM has the following known issues:
- The `current` link is **not returned**.
- The `first` and `last` links are **not always returned**.
- The `prev` link is omitted on both the first **and** second pages. It should only be omitted on the first page.
- The `next` link is omitted on both the last **and** second-to-last pages. It should only be omitted on the last page.
#### Planned behaviour (on or after 1 September 2026)
On or after 1 September 2026, PIM list endpoints will adopt the following pagination link behaviour, aligning with the rest of the platform:
- `current` — always present, pointing to the current page.
- `first` — always present.
- `last` — present on all pages **except the final page**. Omitting `last` on the final page is intentional, to avoid triggering infinite‑loop bugs in integration code that uses the presence of `last` to detect whether more pages remain.
- `next` — present on all pages except the last page.
- `prev` — present on all pages except the first page.
'
properties:
current:
description: 'A link to the current page of results. **Note:** this link is not currently returned by PIM endpoints. It will be introduced on or after 1 September 2026.
'
type: string
example: /pcm/hierarchies?page[offset]=10&page[limit]=10
first:
description: 'A link to the first page of results. Currently this may not always be present. After the planned changes it will always be present.
'
type: string
example: /pcm/hierarchies?page[offset]=0&page[limit]=10
last:
description: 'A link to the last page of results. Currently this may not always be present. After the planned changes it will be present on all pages except the final page (where it is intentionally omitted).
'
type: string
example: /pcm/hierarchies?page[offset]=20&page[limit]=10
next:
description: 'A link to the next page of results. Should be absent on the last page. Currently this is incorrectly absent on the second-to-last page as well; this will be fixed on or after 1 September 2026.
'
type: string
example: /pcm/hierarchies?page[offset]=10&page[limit]=10
prev:
description: 'A link to the previous page of results. Should be absent on the first page. Currently this is incorrectly absent on the second page as well; this will be fixed on or after 1 September 2026.
'
type: string
example: /pcm/hierarchies?page[offset]=8&page[limit]=10
multi_custom_relationships:
type: object
required:
- data
- meta
properties:
data:
type: array
items:
$ref: '#/components/schemas/custom_relationship'
links:
$ref: '#/components/schemas/multi_links_cr'
meta:
$ref: '#/components/schemas/multi_meta'
product_association_response:
type: object
properties:
meta:
type: object
properties:
associated_products:
description: A list of product IDs that have been successfully associated with this custom relationship.
type: array
items:
type: string
example:
- 68c48149-0e94-4ef2-93d5-8d5f3774980a
- ab4826d1-4a5a-4951-a2a5-98058899f891
products_not_associated:
description: A list of products that could not be associated, including the reasons why.
type: array
items:
type: object
properties:
ID:
description: The ID of the product that could not be associated.
type: string
example: 97b7fac2-91dd-4755-81b0-bdffe8e7eabd
Details:
description: Details about why the product could not be associated.
type: string
example: could not find product
example:
- ID: 97b7fac2-91dd-4755-81b0-bdffe8e7eabd
Details: could not find product
- ID: a0ef3291-2ec1-4d7d-9d6d-1705ae01bb99
Details: product already has 5 custom relationships, cannot associate more as it has reached the limit of 5 custom relationships
- ID: bde79675-4783-40b7-8a7e-ac6df41459c6
Details: product already has 5 custom relationships, cannot associate more as it has reached the limit of 5 custom relationships
- ID: aaddd5f4-a5f8-42e8-be9a-097986f22e58
Details: exceeded maximum allowed associations (2000). Please review and try again
owner:
description: The owner of the resource.
type: string
example: store
timestamps:
type: object
properties:
created_at:
description: The date and time the resource was created.
type: string
example: '2024-08-08T09:29:08.295Z'
format: date-time
updated_at:
description: The date and time the resource was last updated.
type: string
example: '2024-08-08T09:29:08.295Z'
format: date-time
product_association_delete_request:
type: object
required:
- data
properties:
data:
type: array
items:
type: object
required:
- id
- type
properties:
id:
type: string
description: The ID of the product you want to relate.
type:
type: string
enum:
- product
description: This represents the type of resource being returned. Always `product`.
multi_product_response:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/product_response'
included:
$ref: '#/components/schemas/included_response'
links:
$ref: '#/components/schemas/multi_links'
meta:
type: object
properties:
results:
description: Contains the results for the entire collection.
type: object
properties:
total:
description: Total number of results for the entire collection.
type: integer
example: 2
product_locales:
type: object
description: Product Experience Manager supports localization of products and hierarchies. If your store supports multiple languages, you can localize product names and descriptions. You can have as many locales as you want.
additionalProperties:
description: A [three-letter language code](https://www.iso.org/iso-639-language-code) that represents the name of language you have used.
type: object
required:
- name
properties:
name:
type: string
description: A localized name for the product.
description:
type: string
description: A localized description for the product.
included_response:
type: object
description: Included is an array of resources that are included in the response.
properties:
main_images:
description: The main images associated with a product.
type: array
items:
$ref: '#/components/schemas/elastic_path_file'
component_products:
description: Returns a list of component products in a product bundle. If a bundle has no component products (in other words, is not a product bundle), an empty array is returned.
type: array
items:
$ref: '#/components/schemas/product_response'
files:
description: The files associated with a product.
type: array
items:
$ref: '#/components/schemas/elastic_path_file'
multi_meta:
type: object
properties:
results:
description: Contains the results for the entire collection.
type: object
properties:
total:
description: Total number of results for the entire collection.
type: integer
example: 30
minimum: 0
product_association_request:
type: object
required:
- data
properties:
data:
type: array
items:
type: object
required:
- id
- type
properties:
id:
type: string
description: The ID of the product you want to relate.
type:
type: string
enum:
- product
description: This represents the type of resource being returned. Always `product`.
attributes:
type: object
properties:
sort_order:
description: The order in which the product to product should be displayed in relation to others. A lower value represents a higher priority in the display order. If set to NULL, the sort order will be removed.
type:
- integer
- 'null'
example: 5
shopper_attributes:
type: object
description: "`shopper_attributes` are displayed in catalogs. This means `shopper_attributes` can be viewed by both shoppers and administrators. If you do not want a custom attribute to be displayed in a catalog, you must add it to `admin_attributes`. \n\n`shopper_attributes` are structured as key-value pairs. Both the keys and values are `strings`. You can have up to 100 keys.\n"
example:
cost_of_goods: '42.0'
charge_type: credit card
additionalProperties:
type:
- string
- 'null'
product_build_rules:
type: object
description: You can build a combination of child products associated with a product, based on build rules that you specify. This is useful, for example, if you have a variation option that you do not sell. This makes managing and building your child products quick and easy. See [Using Build Rules](/docs/api/pxm/products/build-child-products#using-build-rules).
properties:
default:
description: Specifies the default behaviour, either `include` or `exclude`.
type: string
enum:
- include
- exclude
include:
description: An array of option IDs to include when child products are built. Each combination consists of a nested array of option IDs from one or more variations. Combinations of option IDs in the nested arrays must come from different variations.
type: array
items:
type: array
items:
type: string
exclude:
description: An array of option IDs to exclude when child products are built. Each combination consists of a nested array of option IDs from one or more variations. Combinations of option IDs in the nested arrays must come from different variations.
type: array
items:
type: array
items:
type: string
attach_custom_relationship_request:
type: object
required:
- data
properties:
data:
type: array
items:
type: object
required:
- slug
- type
properties:
slug:
type: string
description: The slug of the custom relationship.
type:
type: string
enum:
- custom-relationship
description: This represents the type of resource. Always `custom-relationship`.
product_response:
type: object
properties:
id:
description: A unique product ID that is generated when you create the product.
type: string
type:
description: This represents the type of resource object being returned. Always `product`.
type: string
enum:
- product
attributes:
type: object
additionalProperties: false
properties:
name:
description: A name for the product.
type: string
description:
description: A description for the product.
type: string
slug:
description: A label for the product that is used in the URL paths. A slug can contain A to Z, a to z, 0 to 9, hyphen, underscore, and period. Spaces or other special characters like ^, [], *, and $ are not allowed. By default, the product name is used as the slug.
type: string
sku:
description: The unique stock keeping unit of the product.
type: string
status:
description: The status for the product, either `draft` or `live`.
type: string
enum:
- live
- draft
commodity_type:
description: The commodity type, either `physical` or `digital`.
type: string
enum:
# --- truncated at 32 KB (63 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/elastic-path/refs/heads/main/openapi/elastic-path-product-relationships-api-openapi.yml