Elastic Path Product Relationships API

The Product Relationships API from Elastic Path — 3 operation(s) for product relationships.

OpenAPI Specification

elastic-path-product-relationships-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  version: 25.1126.6886238
  x-version-timestamp: 2025-11-26 19:10:23+00:00
  title: Addresses Introduction Account Addresses Product Relationships API
  description: 'The Addresses API allows you to organize account addresses. Addresses are a sub-resource of `account` resources, an account can have multiple addresses, such as home, work, and neighbour.


    You can use an account address with either [client_credentials access token](/docs/api/authentication/create-an-access-token) or a combination of [implicit access token](/docs/api/authentication/create-an-access-token) and [Account Management authentication](/docs/api/accounts/post-v-2-account-members-tokens) token.

    '
  contact:
    name: Elastic Path
    url: https://www.elasticpath.com
    email: support@elasticpath.com
  license:
    url: https://elasticpath.dev
    name: MIT
servers:
- url: https://useast.api.elasticpath.com
  description: US East
- url: https://euwest.api.elasticpath.com
  description: EU West
security:
- BearerToken: []
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:
  schemas:
    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_links_cr:
      type: object
      description: Links are used to allow you to move between requests.
      properties:
        first:
          description: Always the first page.
          type: string
          example: /pcm/custom_relationships?page[offset]=0&page[limit]=10
        last:
          description: This is `null` if there is only one page.
          type: string
          example: /pcm/custom_relationships?page[offset]=20&page[limit]=10
        next:
          description: This is `null` if there is only one page.
          type: string
          example: /pcm/custom_relationships?page[offset]=10&page[limit]=10
        prev:
          description: This is `null` if you on the first page.
          type: string
          example: /pcm/custom_relationships?page[offset]=8&page[limit]=10
    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
    custom_relationship:
      type: object
      required:
      - id
      - type
      - attributes
      - meta
      properties:
        id:
          description: A unique identifier generated when a custom relationship is created.
          type: string
        type:
          description: This represents the type of resource object being returned. Always `custom-relationship`.
          type: string
          enum:
          - custom-relationship
        attributes:
          $ref: '#/components/schemas/req_attributes_custom_relationship'
        meta:
          type: object
          required:
          - owner
          - timestamps
          properties:
            owner:
              description: The owner of the resource.
              type: string
              example: store
            timestamps:
              type: object
              required:
              - created_at
              - updated_at
              properties:
                created_at:
                  description: The date and time the resource is created.
                  type: string
                  example: '2024-01-10T20:16:35.343Z'
                  format: date-time
                updated_at:
                  description: The date and time the resource is updated.
                  type: string
                  example: '2024-01-10T20:16:35.343Z'
                  format: date-time
    error:
      required:
      - errors
      properties:
        errors:
          type: array
          items:
            required:
            - status
            - title
            properties:
              status:
                type: string
                description: The HTTP response code of the error.
                example: '500'
              title:
                type: string
                description: A brief summary of the error.
                example: Internal server error
              detail:
                type: string
                description: Optional additional detail about the error.
                example: An internal error has occurred.
              request_id:
                type: string
                description: Internal request ID.
                example: 00000000-0000-0000-0000-000000000000
              meta:
                type: object
                description: Additional supporting meta data for the error.
                example:
                  missing_ids:
                  - e7d50bd5-1833-43c0-9848-f9d325b08be8
    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
    req_attributes_custom_relationship:
      type: object
      additionalProperties: false
      required:
      - name
      - slug
      properties:
        name:
          description: The name of the custom relationship to display to shoppers, such as `Kitchen electrics`.
          type: string
          example: Related Products
        description:
          description: A description of the custom relationship.
          type: string
          example: A list of related products shown on the PDP.
        slug:
          description: A unique slug for the custom relationship. Must match the slug specified in the request path. 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.
          type: string
          example: CRP_related_products
          pattern: ^[A-Za-z0-9._-]+$
        sort_order:
          description: The order in which the custom relationship 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.
          nullable: true
          type: integer
          example: 5
        external_name:
          description: The shopper-facing name for the custom relationship. This value will be displayed to shoppers in the store-front, replacing the internal name if present. If set to NULL, the external name will be removed.
          nullable: true
          type: string
          example: Similar items to consider
        external_description:
          description: The shopper-facing description for the custom relationship. This value will be shown to shoppers in the store-front, replacing the internal description if present. If set to NULL, the external description will be removed.
          nullable: true
          type: string
          example: Check out these similar products that may also meet your needs or match your preferences.
        bi_directional:
          type: boolean
          description: Is this relationship one way or bi-directional `true` or `false`. Default is false
          default: false
    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`.
    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
    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:
        nullable: true
        type: string
    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
    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_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
    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:
        nullable: true
        type: string
    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'
    product_association_list_product_ids_response:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            type: object
            required:
            - id
            - type
            properties:
              id:


# --- truncated at 32 KB (62 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/elastic-path/refs/heads/main/openapi/elastic-path-product-relationships-api-openapi.yml