diff --git a/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.graphqls b/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.graphqls
new file mode 100644
index 000000000..19c857376
--- /dev/null
+++ b/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.graphqls
@@ -0,0 +1,214 @@
+type Query {
+    customAttributeMetadataV2(attributes: [AttributeMetadataInput!]!): CustomAttributeMetadata
+    customAttributesLists(listType: CustomAttributesListsEnum): CustomAttributeMetadata
+}
+
+type AttributeMetadataInput {
+    attribute_uid: ID
+}
+
+type CustomAttributeMetadata { # this replaces existing Attribute type
+    items: [AttributeMetadataInterface]
+}
+
+interface AttributeMetadataInterface { # base metadata common to all attributes
+    uid: ID # base64Encode(entityID/codeID)
+    label: String
+    data_type: ObjectDataTypeEnum # string, int, float, boolean etc
+    sort_order: Int
+    entity_type: EntityTypeEnum
+    ui_input: UiInputTypeInterface!
+}
+
+type CustomerAttributeMetadata implements AttributeMetadataInterface {
+    forms_to_use_in: [CustomAttributesListsEnum]
+}
+
+type CustomerAddressAttributeMetadata implements AttributeMetadataInterface {
+}
+
+type ProductAttributeMetadata implements AttributeMetadataInterface {
+    lists_to_use_in: [CustomAttributesListsEnum]
+}
+
+# interfaces for different types used in inputs --------------
+
+interface UiInputTypeInterface {
+    ui_input_type: EntityTypeEnum
+    is_value_required: Boolean!
+}
+
+interface ValidationTextInputTypeInterface {
+    filter: InputValidationFilterEnum
+}
+
+interface FilterableTextInputTypeInterface {
+    input_validation: FilterableText
+}
+
+interface AttributeOptionsInterface {
+    attribute_options: [AttributeOptionInterface]
+}
+
+interface AttributeOptionInterface {
+    uid: ID!
+    is_default: Boolean
+    label: String
+}
+
+interface SelectableInputTypeInterface {
+
+}
+
+interface TextInputTypeInterface {
+    default_value: String
+}
+
+type FilterableText {
+    input_validation_type: InputValidationTypeEnum
+    minimum_text_length: Int
+    maximum_text_length: Int
+}
+
+type TextUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
+
+}
+
+type TextAreaUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
+
+}
+
+type MultipleLineUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
+    lines_count: Int
+}
+
+type DateUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    minimum_date_allowed: String
+    maximum_date_allowed: String
+}
+
+type FileUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    maximum_file_size: Int # bytes
+    allowed_file_extensions: [String]
+}
+
+type ImageUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    maximum_file_size: Int # bytes
+    allowed_file_extensions: [String]
+    maximum_image_width: Int # in pixels
+    maximum_image_height: Int # in pixels
+}
+
+type DropDownUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface {
+}
+
+type MultipleSelectUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface {
+}
+
+interface SwatchInputTypeInterface {
+    update_product_preview_image: Boolean
+}
+
+type VisualSwatchUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface, SwatchInputTypeInterface {
+    use_product_image_for_swatch_if_possible: Boolean
+}
+
+type TextSwatchUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface, SwatchInputTypeInterface {
+
+}
+
+type AttributeOption implements AttributeOptionInterface {
+    value: String @deprecated(reason: "use `uid` instead")
+    label: String
+}
+
+interface SelectableInputTypeInterface {
+
+}
+
+type ColorSwatchAttributeOption implements AttributeOptionInterface {
+    color: String # html hex code format
+}
+
+type ImageSwatchAttributeOption implements AttributeOptionInterface {
+    image_path: String # relative path
+}
+
+type TextSwatchAttributeOption implements AttributeOptionInterface {
+    description: String
+}
+
+#enums to support above queries
+enum ObjectDataTypeEnum {
+    STRING
+    FLOAT
+    INT
+    BOOLEAN
+}
+
+enum EntityTypeEnum {
+    CUSTOMER
+    CUSTOMER_ADDRESS
+    CATALOG_CATEGORY
+    CATALOG_PRODUCT
+    ORDER
+    INVOICE
+    CREDITMEMO
+    SHIPMENT
+    RMA_ITEM
+    GENERIC
+}
+
+enum UiInputTypeEnum {
+    TEXT
+    TEXTAREA
+    MULTILINE
+    DATE
+    DATETIME
+    SELECT
+    MULTISELECT
+    BOOLEAN
+    FILE
+    IMAGE
+    SWATCH_VISUAL
+    SWATCH_TEXT
+    PRICE
+    MEDIA_IMAGE
+    WEEE
+}
+
+enum InputValidationTypeEnum {
+    ALPHANUMERIC
+    ALPHANUMERIC_WITH_SPACES
+    NUMERIC_ONLY
+    ALLPHA_ONLY
+    DATE
+    URL
+    EMAIL
+    LENGTH_ONLY
+}
+
+enum InputValidationFilterEnum {
+    STRIPTAGS
+    ESCAPEHTML
+    DATE
+}
+
+enum CustomerAttributeFormsEnum {
+    CUSTOMER_ACCOUNT_CREATE
+    CUSTOMER_ACCOUNT_EDIT
+    ADMINHTML_CHECKOUT
+}
+
+enum CustomAttributesListsEnum {
+    PRODUCTS_COMPARE
+    PRODUCTS_LISTING
+    ADVANCED_CATALOG_SEARCH
+    PRODUCT_SORT
+    PRODUCT_FILTER
+    PRODUCT_SEARCH_RESULTS
+    PRODUCT_AGGREGATIONS
+    RMA_FORM
+    CUSTOMER_REGISTRATION_FORM
+    CUSTOMER_ADDRESS_FORM
+}
diff --git a/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.md b/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.md
index 9d4b868c5..3a1d64047 100644
--- a/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.md
+++ b/design-documents/graph-ql/coverage/custom-attributes/attributes-metadata.md
@@ -11,49 +11,137 @@ Additionally, there should be a way to retrieve metadata for all storefront cust
 
 # Proposed solution
 
-Relaxing signature of existing `customAttributeMetadata` query by making its `attriubtes` argument optional will allow to fetch all storefront attributes metadata.
+Relaxing signature of existing `customAttributeMetadata` query by making its `attributes` argument optional will allow to fetch all storefront attributes metadata.
 
 Existing schema:
 ```graphql
-Query.customAttributeMetadata(
+Query.customAttributesMetadata(
     attributes: [AttributeInput!]!
 ): CustomAttributeMetadata
+```
+
+Added schema:
+
+```graphql
+Query.customAttributesMetadataV2(
+    attributes: [AttributeMetadataInput!]
+): CustomAttributeMetadata
+
+#adding to existing type a choice of uid or code and 
+input AttributeMetadataInput {
+    attribute_uid: ID
+}
+
+type CustomAttributeMetadata { # this replaces existing Attribute type
+    items: [AttributeMetadataInterface]
+}
+
+interface AttributeMetadataInterface { # base metadata common to all attributes
+    uid: ID # base64Encode(entityID/codeID)
+    label: String
+    data_type: ObjectDataTypeEnum # string, int, float, boolean etc
+    sort_order: Int
+    entity_type: EntityTypeEnum
+    ui_input: UiInputTypeInterface!
+}
+
+type CustomerAttributeMetadata implements AttributeMetadataInterface {
+    forms_to_use_in: [CustomAttributesListsEnum]
+}
+
+type CustomerAddressAttributeMetadata implements AttributeMetadataInterface {
+}
+
+type ProductAttributeMetadata implements AttributeMetadataInterface {
+    lists_to_use_in: [CustomAttributesListsEnum]
+}
+
+type TextUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
+
+}
+
+type TextAreaUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
 
-type AttributeInput {
-    attribute_code: String
-    entity_type: String
 }
 
-type CustomAttributeMetadata {
-    items: [Attribute]
+type MultipleLineUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface, ValidationTextInputTypeInterface {
+    lines_count: Int
 }
 
-type Attribute {
-    attribute_code: String
-    attribute_options: [AttributeOption]
-    attribute_type: String
-    entity_type: String
-    input_type: String
+type DateUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    minimum_date_allowed: String
+    maximum_date_allowed: String
 }
 
-type AttributeOption {
+type FileUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    maximum_file_size: Int # bytes
+    allowed_file_extensions: [String]
+}
+
+type ImageUiInputType implements UiInputTypeInterface, TextInputTypeInterface, FilterableTextInputTypeInterface {
+    maximum_file_size: Int # bytes
+    allowed_file_extensions: [String]
+    maximum_image_width: Int # in pixels
+    maximum_image_height: Int # in pixels
+}
+
+type DropDownUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface {
+}
+
+type MultipleSelectUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface {
+}
+
+interface SwatchInputTypeInterface {
+    update_product_preview_image: Boolean
+}
+
+type VisualSwatchUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface, SwatchInputTypeInterface {
+    use_product_image_for_swatch_if_possible: Boolean
+}
+
+type TextSwatchUiInputType implements UiInputTypeInterface, SelectableInputTypeInterface, AttributeOptionsInterface, SwatchInputTypeInterface {
+
+}
+
+type AttributeOption implements AttributeOptionInterface {
+    value: String @deprecated(reason: "use `uid` instead")
     label: String
-    value: String
+}
+
+type ColorSwatchAttributeOption implements AttributeOptionInterface {
+    color: String # html hex code format
+}
+
+type ImageSwatchAttributeOption implements AttributeOptionInterface {
+    image_path: String # relative path
+}
+
+type TextSwatchAttributeOption implements AttributeOptionInterface {
+    description: String
 }
 ```
 
 Additional fields should be added to the metadata response (`Attribute`  type), for example `is_dynamic`, `use_in_compare_products`, `display_in_product_listing`, `use_in_advanced_search`, `advanced_search_input_type`. The exact list of fields must be discussed and approved separately.
 
-Introduction of the following query will allow fetching lists of attributes applicable to specific pages:
+See full schema [attributes-metadata.graphqls](attributes-metadata.graphqls)
+
+Introduction of the following query will allow fetching lists of attributes applicable to specific artifacts/listings:
 ```graphql
-pageSpecificCustomAttributes(
-    page_type: CustomAttributesPageEnum
+customAttributesLists(
+    listType: CustomAttributesListingsEnum
 ): CustomAttributeMetadata
 
-enum CustomAttributesPageEnum {
+enum CustomAttributesListingsEnum {
     PRODUCTS_COMPARE
     PRODUCTS_LISTING
     ADVANCED_CATALOG_SEARCH
+    PRODUCT_SORT
+    PRODUCT_FILTER
+    PRODUCT_SEARCH_RESULTS
+    PRODUCT_AGGREGATIONS
+    RMA_FORM
+    CUSTOMER_REGISTRATION_FORM
+    CUSTOMER_ADDRESS_FORM
 }
 ```
 
diff --git a/design-documents/graph-ql/coverage/custom-attributes/custom-attributes-container.md b/design-documents/graph-ql/coverage/custom-attributes/custom-attributes-container.md
index 3b22cf763..afd20409d 100644
--- a/design-documents/graph-ql/coverage/custom-attributes/custom-attributes-container.md
+++ b/design-documents/graph-ql/coverage/custom-attributes/custom-attributes-container.md
@@ -8,13 +8,156 @@ One workaround for "getting all fields" is based on schema introspection, it all
 
 # Proposed solution
 
-To account for dynamic nature of EAV attributes and the need of "getting all fields" in product search queries, `custom_attributes: [CustomAttribute]!` container will be introduced. 
+To account for dynamic nature of EAV attributes and the need of "getting all fields" in product search queries, we can introduce `custom_attributes: [CustomAttribute]!` container (recommended approach). 
+The container will return the list of attributes plus the actual values stored for each entity. 
 
 ```graphql
 type CustomAttribute {
+  selected_attribute_options: [SelectedAttributeOption] # used to store unique options values
+  entered_attribute_value: EnteredAttributeValue # used to store the freetype entered values like texts 
+  attribute_metadata: AttributeMetadataInterface # metadata of the actual attribute not related to the stored Entity-Attribute value
+}
+
+type SelectedAttributeOption {
+  attribute_option: AttributeOptionInterface
+  attribute_metadata: AttributeMetadataInterface
+}
+
+type EnteredAttributeValue {
+  attribute_metadata: AttributeMetadataInterface
+  value: String
+}
+```
+
+We could also make value complex type to be able add more complex fields values in the future, but this doesn't seem necessary at this point.
+This is also aligned with the Selected, Entered values from customizable options, or configurable product.
+
+As for the attribute we would define a concrete type for each entity, because each entity's attributes are different and values of attributes are also complext
+For this reason interfaces on multiple levels are the best approach for composability purposes and satisfying values needs like swatches.
+
+```graphql
+type EntityAttributeMetadata implements AttributeMetadataInterface, AttributeMetadataEntityTypeInterface, AttributeMetadataUiTypeInterface {
+    ui_input_type: UiInputTypeInterface!
+    forms_to_use_in: [CustomAttributesListingsEnum]
+}
+# --------
+interface AttributeMetadataInterface { # base metadata common to all attributes
+    uid: ID # base64Encode(entityID/codeID)
+    label: String
+    data_type: ObjectDataTypeEnum # string, int, float, boolean etc
+    sort_order: Int
+    entity_type: EntityTypeEnum
+    ui_input: UiInputTypeInterface!
+}
+```
+#### Sample queries for this alternative
+```graphql
+{
+  customner {
+    custom_attributes {
+      selected_attribute_options {
+        attribute_option {
+          uid
+          is_default
+          ... on AttributeOption {
+            label
+            is_default
+          }
+        }
+        attribute_metadata {
+          uid
+          code
+          label
+        }
+      }
+      entered_attribute_value {
+        attribute_metadata {
+          uid
+          code
+          label
+        }
+        value
+      }
+      attribute_metadata {
+         uid
+         code
+         label # all attributes have a label per store
+         data_type # enum : string, int, float etc
+         sort_order # needed for ordering
+
+         entity_type # enum
+         ... on CustomerAttributeMetadata {
+             forms_to_use_in # only in CustomerAttributeMetadata
+         }
+         ... on ProductAttributeMetadata {
+             lists_to_use_in # only in ProductAttributeMetadata. As opposed to Customer which only had forms
+         }
+         ui_input {
+             __typename
+             ui_input_type
+             is_value_required
+             ... on SelectableInputTypeInterface {
+                 ... on SwatchInputTypeInterface {
+                     update_product_preview_image
+                 }
+                 ... on VisualSwatchInputType {
+                     use_product_image_for_swatch_if_possible
+                 }
+                 attribute_options {
+                     uid
+                     is_default
+                     label
+                     ... on ColorSwatchAttributeOption {
+                         color
+                     }
+                     ... on ImageSwatchAttributeOption {
+                         image_path
+                     }
+                     ... on TextSwatchAttributeOption {
+                         description
+                     }
+                 }
+             }
+             ... on TextInputTypeInterface {
+                 default_value # string
+                 ... on FilterableTextInputTypeInterface {
+                     filter # enum
+                 }
+                 ... on ValidationTextInputTypeInterface {
+                     input_validation {
+                         input_validation_type
+                         minimum_text_length
+                         maximum_text_length
+                     }
+                 }
+             }
+         }
+      }
+    }
+  }
+}
+```
+
+### Alternatives considered
+```graphql
+type CustomAttribute {
+    code: String!
+    values: [String]! # We want to account fo attributes that have single (text, dropdown) and multiple values (checkbox, multiselect)
+}
+```
+
+```graphql
+interface CustomAttributeInterface {
     code: String!
+}
+
+type SingleValueCustomAttribute implements CustomAttributeInterface {
     value: String!
 }
+
+type MultipleValuesCustomAttribute implements CustomAttributeInterface {
+    values: [String]!
+}
 ```
 
 Here `value` is JSON-encoded value of the custom attribute.
@@ -23,7 +166,7 @@ Flat representation of custom attributes in `ProductInterface` (and other EAV en
 
 It is necessary to keep in mind that with `custom_attributes` it is not possible to query product EAV attributes selectively, which may lead to performance degradation.
 
-### Sample queries
+#### Sample queries for this alternative
 
 Current implementation allows the following query
 ```graphql
@@ -42,7 +185,7 @@ Current implementation allows the following query
 
 Let's assume the response will be
 
-```graphql
+```json
 {
   "data": {
     "products": {
@@ -51,14 +194,14 @@ Let's assume the response will be
           "name": "Test Simple Product",
           "sku": "testSimpleProduct",
           "color": "Red",
-          "manufacturer": "Company A"
+          "manufacturer": "Company A",
           "size": null
         },
         {
           "name": "Test Configurable Product",
           "sku": "testConfigProduct",
           "color": null,
-          "manufacturer": "Company B"
+          "manufacturer": "Company B",
           "size": "XXL"
         }
       ]
@@ -85,7 +228,7 @@ With the proposed changes the above mentioned queries will still be supported. I
  ```
 Note that color and size are not applicable to some products in the search result. In the previous example they were returned as `null`. In the following example they are not returned at all
 
-```graphql
+```json
 {
   "data": {
     "products": {
@@ -95,11 +238,11 @@ Note that color and size are not applicable to some products in the search resul
           "sku": "testSimpleProduct",
           "custom_attributes": [
             {
-                "code": "color"
+                "code": "color",
                 "value": "Red"
             },
             {
-                "code": "manufacturer"
+                "code": "manufacturer",
                 "value": "Company A"
             }
           ]
@@ -109,22 +252,22 @@ Note that color and size are not applicable to some products in the search resul
           "sku": "testConfigProduct",
           "custom_attributes": [
             {
-              "code": "manufacturer"
+              "code": "manufacturer",
               "value": "Company B"
             },
             {
-              "code": "size"
+              "code": "size",
               "value": "XXL"
             }
           ]
-        },
+        }
       ]
     }
   }
 }
 ```
 
-# Alternatives considered
+### Other Alternatives considered
 
  1. [Persisted queries](https://github.com/magento/graphql-ce/issues/781) can be leveraged to mitigate described issue with the increased size of the request.
  1. To improve flexibility and allow support of complex structures, `type` can be added to the definition of `CustomAttribute` in the future, if there are valid use cases.