Product disclosures
Product disclosures let merchants attach regulatory safety and compliance content — such as California Proposition 65 warnings or CPSC choking-hazard warnings — to products as structured data instead of free text buried in descriptions, tags, or theme code.
Because disclosures are structured, the same content renders consistently across the Online Store, the Shop app, custom storefronts, checkout, and agentic channels, and it can be syndicated to marketplaces without re-entry. Disclosure copy is preserved verbatim, which is what regulators and agents require.
This guide covers every surface where you can manage disclosures:
- The data model — how disclosures are stored.
- Manage disclosures with the Admin API.
- Read disclosures with the Storefront API.
- Display disclosures in a theme (Liquid).
- Surface disclosures in checkout (Checkout UI extensions).
- Access disclosures from agentic channels (Catalog / UCP).
Disclosures carry legal weight and are distinct from informational labels ("final sale", "limited edition"). The cost of a missing disclosure (legal exposure, channel delisting) is far higher than an unnecessary one, so over-disclosure is the safe default. Merchants own compliance liability; Shopify provides the tooling.
Disclosures carry legal weight and are distinct from informational labels ("final sale", "limited edition"). The cost of a missing disclosure (legal exposure, channel delisting) is far higher than an unnecessary one, so over-disclosure is the safe default. Merchants own compliance liability; Shopify provides the tooling.
Anchor to Data modelData model
A product disclosure is composed of three layers:
| Layer | What it is |
|---|---|
| Disclosure taxonomy | An open, Shopify-governed list of disclosure types published in the public product-taxonomy repo. Each leaf (for example, Prop 65 cancer warning) has a stable ID exposed as gid://shopify/TaxonomyDisclosure/<id>, with default title, content, jurisdictions, legal citation, and symbol. Disclosure is a separate axis of the taxonomy, parallel to product categories, not a child of a category. |
| Disclosure metaobjects | Shop-scoped metaobject entries that hold the disclosure content shown to buyers. Shopify seeds canonical entries from the taxonomy, and merchants can edit them or author custom entries. Multiple entries of the same type are allowed (content can vary per product). |
| Product metafield | A standard product metafield, shopify.disclosure of type list.disclosure_reference, that holds the list of disclosure metaobjects applied to a product. |
Anchor to The product metafieldThe product metafield
| Property | Value |
|---|---|
| Namespace | shopify |
| Key | disclosure |
| Type | list.disclosure_reference |
| Owner type | Product |
| Storefront API visible | Yes |
disclosure_reference is a dedicated metafield type for disclosure metaobjects. It exists as its own type because disclosures have behavior generic references don't: jurisdiction-aware contextualization, native first-party channel rendering, and tailored Admin UX.
Anchor to Disclosure metaobject definitions and entry typesDisclosure metaobject definitions and entry types
Shopify provides standard metaobject definitions, one per disclosure leaf. The metaobject type is the stable, machine-readable identifier and uses a reserved shopify-- prefix so merchant-authored entries can never collide with Shopify-managed ones.
Shopify provides these entry types:
| Group | Entry types |
|---|---|
| Chemical exposure (Prop 65) | shopify--disclosure-us-ca-prop65-cancer, shopify--disclosure-us-ca-prop65-reproductive, shopify--disclosure-us-ca-prop65-cancer_reproductive, shopify--disclosure-us-ca-prop65-alcohol |
| Choking hazards (CPSC) | shopify--disclosure-us-cpsc-choking_small_parts, shopify--disclosure-us-cpsc-choking_balloons, shopify--disclosure-us-cpsc-choking_marbles, shopify--disclosure-us-cpsc-choking_small_balls |
| Custom | shopify--disclosure-custom |
Each entry exposes these fields:
| Field | Type | Required | Description |
|---|---|---|---|
taxonomy_reference | product_taxonomy_disclosure_reference | Yes (not on custom) | Reference to the taxonomy leaf this entry instantiates, set as its GID (for example gid://shopify/TaxonomyDisclosure/<id>). It's a dedicated reference type, not free text; it disambiguates sub-leaves within a disclosure group. |
title | single line text (max 100) | Yes | Buyer-facing heading (for example, "Choking Hazard"). |
internal_label | single line text (max 255) | Yes | Internal-only label that mirrors the disclosure name. Not exposed to the Storefront API. |
content | rich text | No | The disclosure copy, rendered verbatim. Stored as a rich-text JSON document. |
symbol | file reference (Image) | No | The visual symbol (for example, the Prop 65 triangle or ISO 7010 W001), stored as a reference to an image media file. For taxonomized disclosures it's populated automatically from the taxonomy when the entry is created. |
jurisdictions | list of single line text (min 1) | Yes | Jurisdiction codes the disclosure applies to, for example ["US-CA"]. |
display_preferences | JSON | Yes | Which surfaces to render on. The surfaces array accepts product_page, cart, and checkout, for example {"surfaces":["product_page"]}. |
Custom disclosures (shopify--disclosure-custom) are the sanctioned escape hatch for content Shopify doesn't yet standardize. They have no taxonomy_reference because there's no leaf to point at. They still require title, internal_label, jurisdictions, and display_preferences; capture jurisdictions directly on the entry.
Custom disclosures (shopify--disclosure-custom) are the sanctioned escape hatch for content Shopify doesn't yet standardize. They have no taxonomy_reference because there's no leaf to point at. They still require title, internal_label, jurisdictions, and display_preferences; capture jurisdictions directly on the entry.
Anchor to GrainGrain
Disclosures are stored at the product grain. They are not stored per variant; variant-specific cases are handled by over-disclosing at the product level or surfacing variant messages in checkout. When surfaced through the Catalog Lookup API, product-grain disclosures are transformed to the variant grain (see agentic channels).
Anchor to RequirementsRequirements
To work with product disclosures, you need:
- An app that can make authenticated requests to the GraphQL Admin API.
- The
write_productsandwrite_metaobjectsaccess scopes. - To read disclosures from a custom storefront, a Storefront API access token with the
unauthenticated_read_product_listingsandunauthenticated_read_metaobjectsaccess scopes.
Anchor to Manage disclosures with the Admin APIManage disclosures with the Admin API
For product disclosures, use a three-step API flow: create the disclosure metaobject instances, enable the product disclosure metafield definition, then set the metafield value on the product. You can do everything below in the Admin GraphQL API, or perform the equivalent steps in the product details page in the Shopify admin.
Creating a standard disclosure metaobject auto-enables its metaobject definition, so there's no separate step to enable definitions. Enabling the shopify.disclosure metafield definition is separate: it creates the product-level slot but doesn't create any metaobjects or attach them to a product.
Anchor to Step 1: Create the disclosure metaobjectStep 1: Create the disclosure metaobject
Create a disclosure entry with metaobjectCreate. If the shop hasn't enabled the standard metaobject definition for that type, this call enables it before creating the entry. title, internal_label, jurisdictions, and display_preferences are required (plus taxonomy_reference on non-custom types); content is optional. For taxonomized disclosures, the symbol is populated automatically from the taxonomy when the entry is created, so you don't set it. The content field is a rich-text JSON document so the copy renders verbatim. Repeat the call for each disclosure you need to create.
Save the returned metaobject.id; you reference it in Step 3.
Valid TaxonomyDisclosure IDs are 2–5 and 13–16. The handle is merchant-visible and useful as a stable mapping key for CSV import/export and PIM integrations.
Valid TaxonomyDisclosure IDs are 2–5 and 13–16. The handle is merchant-visible and useful as a stable mapping key for CSV import/export and PIM integrations.
Anchor to Step 2: Enable the product disclosure metafield definitionStep 2: Enable the product disclosure metafield definition
Enable the standard shopify.disclosure metafield definition on products with standardMetafieldDefinitionEnable. This creates the product-level metafield definition; it doesn't attach any values to a product.
Anchor to Step 3: Set the product metafield valueStep 3: Set the product metafield value
Set the shopify.disclosure metafield to a JSON list of the disclosure metaobject GIDs returned in Step 1.
Anchor to Reading disclosures in the Admin APIReading disclosures in the Admin API
Query the product metafield and dereference the metaobject fields:
Anchor to CleanupCleanup
To remove disclosure support, delete the metafield definition (optionally removing associated metafields), then delete the metaobject definitions.
Anchor to Bulk and CSVBulk and CSV
- Bulk editor: you can apply taxonomy disclosures to products in bulk through the standard mixed-reference bulk-edit flow (single column).
- CSV import/export: disclosures are imported and exported by metaobject
handle, the same as other mixed-reference metafields. Use a stable handle so external systems (for example, a PIM) can map to the disclosure consistently.
Anchor to Read disclosures with the Storefront APIRead disclosures with the Storefront API
Custom storefronts read disclosures by dereferencing the product metafield's metaobject references.
Two of these fields aren't plain strings, so render them accordingly:
contentcomes back as a rich-text JSON document, not HTML or plain text. Render it through a rich-text renderer (parse the JSON and map its nodes); don't print the rawvalue, or buyers will see JSON.symbolis a file reference. Dereference it throughreference { ... on MediaImage { image { url altText } } }to get a usable image URL. The field's rawvalueis only theMediaImageGID, which won't render as an image.
Filter by jurisdictions against the buyer's market if you want jurisdiction-aware display; the API returns all disclosures applied to the product.
Anchor to Display disclosures in a themeDisplay disclosures in a theme
On the Online Store, disclosures render through a self-contained Liquid section that reads the shopify.disclosure metafield. It renders only when a product has disclosures attached, so it's safe to include in every product template. The section shows disclosures in a collapsible accordion: collapsed shows all titles on one line separated by bullets; expanded shows each disclosure's full content.
Anchor to Add the sectionAdd the section
- In your Shopify admin, go to Online Store > Themes > Edit code.
- Under Sections, click Add a new section and name it
disclosures. - Replace the contents with the section below.
This sample omits the accordion CSS/JS for brevity. Style the accordion to span the full page width — disclosure content needs room to be readable.
This sample omits the accordion CSS/JS for brevity. Style the accordion to span the full page width — disclosure content needs room to be readable.
Anchor to Render the sectionRender the section
How you render depends on your template format.
- JSON templates (Online Store 2.0): open the theme editor on your product template, click Add section, and select Disclosures. The section supports a Heading setting (optional heading above the accordion) and an Open by default setting (whether the accordion starts expanded).
- Liquid templates: add
{% section 'disclosures' %}totemplates/product.liquidwhere you want disclosures to appear.
Anchor to Placement in first-party themesPlacement in first-party themes
The disclosures accordion is designed to be full width, which affects where it can live:
- Dawn: places disclosures in a standalone, full-width section as a sibling below Product information. Dawn's Product information is locked to one column of a two-column grid, so a block there can't be full width. Making disclosures its own section keeps the editor's block order matching the rendered order.
- Horizon: places disclosures in a static block inside Product information (at the bottom). Horizon allows blocks within Product information to render outside the constrained column, so the block stays full width while editor ordering stays accurate.
Merchants can edit the heading, toggle the default open state, move the section/block, and remove it entirely if they prefer to surface disclosures elsewhere.
Anchor to Surface disclosures in checkoutSurface disclosures in checkout
Checkout UI extensions are available only to Shopify Plus merchants.
Checkout UI extensions are available only to Shopify Plus merchants.
Disclosures render natively on the product details page and cart. To also surface them in checkout, use a Checkout UI extension that reads each product's disclosure metaobjects from the Storefront API (see Read disclosures with the Storefront API) and renders them.
The extension needs Storefront API access — the api_access capability in your shopify.extension.toml:
Anchor to Access disclosures from agentic channelsAccess disclosures from agentic channels
Disclosures are exposed to agentic commerce through the Universal Commerce Protocol (UCP) lookup_catalog response, reusing the message_warning schema rather than a new top-level field.
A disclosure is a message with type: "warning" and presentation: "disclosure". The top-level messages[] array is the canonical surface, and each entry is anchored to a product via a JSONPath path. This keeps the bulk case unambiguous: a response with twenty products carrying different disclosures yields twenty messages[] entries, each pointing at its product node.
Disclosures are sourced at the product grain in Core (only active-status entries are returned). Per the UCP contract they're then surfaced to the variant grain in the Catalog response, with one messages[] entry per disclosure anchored by path (no aggregation or dedupe). The shape extends to future variant-grain disclosures via $.products[N].variants[M] without breaking.
Anchor to Jurisdictions and display preferencesJurisdictions and display preferences
- Jurisdictions use country and subdivision codes (for example,
US,US-CA). Regional groupings (EU, NAFTA) are not modeled. For taxonomized disclosures jurisdiction comes from the taxonomy leaf; for custom disclosures, setjurisdictionson the entry. - Display preferences (
{"surfaces": ["product_page"]}) declare which surfaces a disclosure should render on. Thesurfacesarray acceptsproduct_page,cart, andcheckout. Disclosures render natively on the product details page and cart; to render in checkout, use a Checkout UI extension (see Surface disclosures in checkout).