{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown","redocly_category":"Guides","api_domain":"Catalog"},"seo":{"title":"Entity metadata and attribute management","description":"Use the Sales Layer Catalog REST API to inspect and manage Product, Variant, Category, and Custom Entity attributes with practical Beta API recipes.","siteUrl":"https://docs.api.saleslayer.com","image":"/assets/sales-layer-horizontal-dark-green.224c048d0bb386d3c2683ba504140512b6233d3c6cbf706ca81e2e3f2f02dbd0.9c1bb791.svg","keywords":["Sales Layer","Sales Layer API","REST API","OpenAPI","PIM API","Product Information Management API","DAM API","Catalog API","product catalog API","product data synchronization","ecommerce integration API","ERP integration","marketplace integration","image management API","digital asset management API","API integration","Model Context Protocol","MCP server","Sales Layer MCP","AI assistant connector","PIM AI assistant"],"lang":"en-US","meta":[{"name":"og:type","content":"website"},{"name":"og:site_name","content":"Sales Layer REST API Documentation"},{"name":"og:title","content":"Sales Layer REST API Documentation"},{"name":"og:description","content":"Technical REST API docs for Sales Layer PIM, Catalog, DAM, ecommerce, ERP, and marketplace integrations."},{"name":"og:image","content":"/assets/sales-layer-horizontal-dark-green.224c048d0bb386d3c2683ba504140512b6233d3c6cbf706ca81e2e3f2f02dbd0.9c1bb791.svg"},{"name":"twitter:card","content":"summary_large_image"},{"name":"twitter:site","content":"@saleslayer"},{"name":"twitter:title","content":"Sales Layer REST API Documentation"},{"name":"twitter:description","content":"Technical REST API docs for Sales Layer PIM, Catalog, DAM, ecommerce, ERP, and marketplace integrations."},{"name":"twitter:image","content":"/assets/sales-layer-horizontal-dark-green.224c048d0bb386d3c2683ba504140512b6233d3c6cbf706ca81e2e3f2f02dbd0.9c1bb791.svg"}],"llmstxt":{"hide":false,"title":"Sales Layer REST API Documentation","description":"Technical guides and OpenAPI references for Sales Layer DAM and Catalog REST APIs.","sections":[{"title":"Guides","description":"Static API guides for authentication, headers, query parameters, responses, rate limiting, and best practices.","includeFiles":["guides/**/*.md","changelog.md","rest-api-evolution-and-compatibility-policy.md"]},{"title":"API Reference","description":"OpenAPI-based references and API overview pages for Sales Layer REST APIs.","includeFiles":["apis/**/*.md","apis/**/*.yaml"]},{"title":"Postman collections","description":"Importable Postman collection and environment instructions for testing Sales Layer REST APIs.","includeFiles":["postman/**/*.md"]},{"title":"MCP server","description":"Documentation for the Sales Layer MCP Server, its tools, access profiles, and how AI assistants consume the Catalog REST API.","includeFiles":["mcp-server/**/*.md"]}]},"jsonLd":{"@context":"https://schema.org","@type":"WebSite","name":"Sales Layer REST API Documentation","url":"https://docs.api.saleslayer.com/","publisher":{"@type":"Organization","name":"Sales Layer","url":"https://www.saleslayer.com/"}}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"entity-metadata-and-attribute-management","__idx":0},"children":["Entity metadata and attribute management"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Catalog REST API can describe an entity's attributes and manage their definitions. An integration can discover the fields a tenant has configured, inspect where an attribute appears on a form, and create or change custom attributes through REST requests. This supports tenant-specific integrations that discover their schema and manage attribute definitions programmatically."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Beta scope:"]}," The attribute-management operations under the four ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/.../attributes"]}," route families below are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Beta"]},". Their public contract can change while they remain in Beta, including incompatible changes identified in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/changelog"},"children":["changelog"]},". Other Catalog operations retain their documented Stable status. See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/rest-api-evolution-and-compatibility-policy"},"children":["REST API Evolution and Compatibility Policy"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The existing JSON Schema endpoints such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /catalog/$metadata"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /catalog/Products/$metadata"]}," describe resource fields and relationships. Their names alone do not make them part of this Beta attribute-management surface. Use the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/catalog-v2.0"},"children":["Catalog endpoint reference"]}," for each operation's full request and response contract."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"supported-entity-routes","__idx":1},"children":["Supported entity routes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each route family supports listing attributes (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]},"), reading one (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../attributes('{attributeId}')"]},"), creating one (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]},"), changing one (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH"]},"), and deleting one (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DELETE"]},")."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Entity"},"children":["Entity"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Attribute collection path after /catalog"},"children":["Attribute collection path after ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/catalog"]}]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Categories"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/Categories/attributes"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Products"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/Products/attributes"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Variants"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/Variants/attributes"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Custom Entities"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/CustomEntities('{customEntityDenominator}')/attributes"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-API-KEY"]}," on every request. Write operations require an API key permitted to make the change. The examples below use Product attribute set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["7"]}," and illustrative identifiers; replace them with values from your tenant."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recipe-discover-attributes-for-a-product-form","__idx":2},"children":["Recipe: discover attributes for a Product form"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["List the custom attributes and request a page of up to 20. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["attributeSetId"]}," selects the form used to report placement; it does not limit the attributes in the Product definition."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --get 'https://api2.saleslayer.com/catalog/Metadata/Products/attributes' \\\n  --data-urlencode 'attributeSetId=7' \\\n  --data-urlencode \"\\$filter=kind eq 'custom'\" \\\n  --data-urlencode '$top=20' \\\n  -H 'X-API-KEY: YOUR_API_KEY'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response contains an attribute summary array in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["value"]},", a total in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@count"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@nextLink"]}," while another page exists. Follow the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@nextLink"]}," to continue. A list item includes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["placement"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["editability"]},"; read an individual attribute when you need type-specific details such as checklist ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["options"]}," or table ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["templates"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X GET \"https://api2.saleslayer.com/catalog/Metadata/Products/attributes('prod_boxmaterial')?attributeSetId=7\" \\\n  -H 'X-API-KEY: YOUR_API_KEY'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The single-attribute response returns the attribute under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["value"]},". Its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["placement"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," when the selected form does not show it. These read operations also support Categories, Variants, and Custom Entities through the paths above. List operations support ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$filter"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$top"]}," from 1 to 100, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$skip"]}," of 0 or greater."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recipe-add-a-product-attribute-to-an-attribute-set-form","__idx":3},"children":["Recipe: add a Product attribute to an attribute set form"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a short-text attribute on the form for Product attribute set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["7"]},". The API derives its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["identifier"]}," from the title and returns the created attribute under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["value"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["201 Created"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST 'https://api2.saleslayer.com/catalog/Metadata/Products/attributes' \\\n  -H 'X-API-KEY: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"type\": \"shortText\",\n    \"title\": \"Box material\",\n    \"pageTitle\": \"Logistics\",\n    \"fieldSize\": \"half\",\n    \"attributeSet\": { \"id\": 7 }\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["value.identifier"]}," for later reads or changes. Products and Variants accept ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["attributeSet"]}," in a create or update body to choose a form. Categories and Custom Entities have no attribute sets. The endpoint reference describes the supported attribute types and their type-specific fields."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recipe-change-a-definition-without-replacing-its-values","__idx":4},"children":["Recipe: change a definition without replacing its values"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Read the attribute first, then send a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH"]}," with its current ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}," and the fields to change. This example renames an existing Product short-text attribute; omitted fields, or fields sent as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},", keep their existing values. A successful update returns the current attribute under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["value"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200 OK"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X PATCH \"https://api2.saleslayer.com/catalog/Metadata/Products/attributes('prod_boxmaterial')\" \\\n  -H 'X-API-KEY: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{ \"type\": \"shortText\", \"title\": \"Case material\" }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check the type-specific update rules before changing an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["options"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["templates"]}," list: a supplied list replaces the whole existing list. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["deleteExistingValues"]}," field empties existing item values, so leave it out for a metadata-only change."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recipe-remove-an-attribute-from-one-form","__idx":5},"children":["Recipe: remove an attribute from one form"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For Products and Variants, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onlyFromForm=true"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["attributeSetId"]}," removes an attribute from that attribute set's form while keeping the definition and existing item values. This request returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["204 No Content"]}," when applied."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X DELETE \"https://api2.saleslayer.com/catalog/Metadata/Products/attributes('prod_boxmaterial')?onlyFromForm=true&attributeSetId=7\" \\\n  -H 'X-API-KEY: YOUR_API_KEY'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onlyFromForm=true"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DELETE"]}," removes the custom attribute from the definition and every Product form, and every Product loses its value. Review the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/catalog-v2.0"},"children":["delete operation"]}," before using that mode."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recipe-inspect-a-custom-entity-definition","__idx":6},"children":["Recipe: inspect a Custom Entity definition"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Supply the Custom Entity denominator to inspect the tenant's attributes for that entity. For example, to list custom attributes of a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Stores"]}," entity:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --get \"https://api2.saleslayer.com/catalog/Metadata/CustomEntities('Stores')/attributes\" \\\n  --data-urlencode \"\\$filter=kind eq 'custom'\" \\\n  --data-urlencode '$top=20' \\\n  -H 'X-API-KEY: YOUR_API_KEY'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use each returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["identifier"]}," to read its full definition at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/Metadata/CustomEntities('Stores')/attributes('{attributeId}')"]},". This route family has no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["attributeSetId"]}," parameter."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"related-pages","__idx":7},"children":["Related pages"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/catalog"},"children":["Catalog REST API overview"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/catalog-v2.0"},"children":["Catalog endpoint reference"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/pagination-and-filtering"},"children":["Pagination and filtering"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/rest-api-evolution-and-compatibility-policy"},"children":["REST API Evolution and Compatibility Policy"]}]}]}]},"headings":[{"value":"Entity metadata and attribute management","id":"entity-metadata-and-attribute-management","depth":1},{"value":"Supported entity routes","id":"supported-entity-routes","depth":2},{"value":"Recipe: discover attributes for a Product form","id":"recipe-discover-attributes-for-a-product-form","depth":2},{"value":"Recipe: add a Product attribute to an attribute set form","id":"recipe-add-a-product-attribute-to-an-attribute-set-form","depth":2},{"value":"Recipe: change a definition without replacing its values","id":"recipe-change-a-definition-without-replacing-its-values","depth":2},{"value":"Recipe: remove an attribute from one form","id":"recipe-remove-an-attribute-from-one-form","depth":2},{"value":"Recipe: inspect a Custom Entity definition","id":"recipe-inspect-a-custom-entity-definition","depth":2},{"value":"Related pages","id":"related-pages","depth":2}],"frontmatter":{"seo":{"title":"Entity metadata and attribute management","description":"Use the Sales Layer Catalog REST API to inspect and manage Product, Variant, Category, and Custom Entity attributes with practical Beta API recipes."},"keywords":{"includes":["entity metadata","attribute management","Catalog REST API","Product attributes","Variant attributes","Category attributes","Custom Entity attributes"]},"metadata":{"redocly_category":"Guides","api_domain":"Catalog"}},"lastModified":"2026-11-05T07:56:58.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/entity-metadata","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}