---
title: Customer Privacy API
description: >-
  The Customer Privacy API provides access to the buyer's tracking consent
  preferences and lets your extension apply consent changes. Use this API to
  build consent banners, check current consent decisions for analytics,
  marketing, and data sale, and save updated preferences.
api_version: 2027-01
source_url:
  html: >-
    https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/target-apis/account-apis/customer-privacy-api
  md: >-
    https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/target-apis/account-apis/customer-privacy-api.md
api_name: customer-account-ui-extensions
---

# Customer Privacy API

**Requires access to [protected customer data](https://shopify.dev/docs/apps/store/data-protection/protected-customer-data). The `region` property requires level 1 access. The `applyTrackingConsentChange` property requires the [`collect_buyer_consent` capability](https://shopify.dev/docs/apps/build/customer-accounts/capabilities#collect-buyer-consent).:**

The Customer Privacy API provides access to the buyer's tracking consent preferences and lets your extension apply consent changes. Use this API to build consent banners, check current consent decisions for analytics, marketing, and data sale, and save updated preferences.

### Use cases

* **Display a consent banner**: Determine whether to show a cookie consent banner when the page loads.
* **Read current consent state**: Check the buyer's current preferences for analytics, marketing, and data sharing.
* **Apply consent changes**: Save the buyer's updated consent preferences after they interact with your consent UI.
* **Handle regional requirements**: Detect if the buyer is in a jurisdiction requiring specific opt-out controls, such as CCPA in California.

### Support Targets (24)

### Supported targets

* [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/footer#footer-render-after-)
* [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-actions#order-index-announcement-)
* [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-actions#order-index-block-)
* [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-status#order-status-announcement-)
* [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-status#order-status-block-)
* [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-status#cart-line-item-render-after-)
* [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-status#cart-line-list-render-after-)
* [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-status#customer-information-render-after-)
* [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/fulfillment-status#fulfillment-status-targets)
* [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/payments-and-returns#payments-and-returns-targets)
* [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/payments-and-returns#return-details-render-after-)
* [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/fulfillment-status#unfulfilled-items-render-after-)
* [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-actions#order-action-menu-item-)
* [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/order-actions#order-action-)
* [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/full-page#order-specific-full-page-)
* [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/full-page#customer-account-full-page-)
* [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-default#profile-page-default-targets-)
* [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-default#profile-announcement-)
* [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-default#profile-block-)
* [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-b2b#profile-page-b2b-targets-)
* [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-b2b#company-location-addresses-render-after-)
* [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-b2b#company-location-payment-render-after-)
* [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc/targets/profile-page-b2b#company-location-staff-render-after-)
* customer-account.​profile.​payment.​render-after

### Properties

The [`shopify` global object](https://shopify.dev/docs/api/customer-account-ui-extensions/2027-01-rc#target-apis-define-what-your-extension-does) provides the customer privacy data and consent management methods. Access the following properties on `shopify` to read privacy consent settings and apply consent changes.

* **apply​Tracking​Consent​Change**

  **ApplyTrackingConsentChangeType**

  **required**

  Applies updated tracking consent preferences for the buyer, including their decisions for analytics, marketing, and data sale, along with any custom tracking consent [metafields](https://shopify.dev/docs/apps/build/custom-data/metafields). Returns a promise that resolves with the result of the consent update.

  [](https://shopify.dev/apps/store/data-protection/protected-customer-data)Requires the [`collect_buyer_consent` capability](https://shopify.dev/docs/apps/build/customer-accounts/capabilities#collect-buyer-consent) and access to [protected customer data](https://shopify.dev/docs/apps/store/data-protection/protected-customer-data).

* **customer​Privacy**

  **SubscribableSignalLike\<CustomerPrivacy>**

  **required**

  The buyer's current privacy consent settings, including their consent decisions for analytics, marketing, and data sale, whether a consent banner should be displayed, and whether the buyer is in a region that requires specific opt-out controls. Use this to read the buyer's consent state and determine how to display privacy-related UI.

### ApplyTrackingConsentChangeType

A function that applies updated tracking consent preferences for the buyer. Accepts a \`VisitorConsentChange\` object containing the buyer's consent decisions and returns a promise that resolves with a \`TrackingConsentChangeResult\` indicating whether the update succeeded or failed.

* visitorConsent

  ```ts
  VisitorConsentChange
  ```

returns

```ts
Promise<TrackingConsentChangeResult>
```

### VisitorConsentChange

The consent change payload passed to \`applyTrackingConsentChange\`. Includes the visitor's updated consent decisions for analytics, marketing, preferences, and data sale, along with any custom tracking consent metafields.

* analytics

  Whether the visitor has consented to analytics tracking. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* marketing

  Whether the visitor has consented to marketing and targeted advertising. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* metafields

  Custom tracking consent metafield data to save alongside the standard consent categories. Use metafields to store app-specific consent granularity beyond the built-in categories. If a metafield's value is \`null\`, that metafield is deleted.

  ```ts
  TrackingConsentMetafieldChange[]
  ```

* preferences

  Whether the visitor has consented to storing preferences such as language and currency. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* saleOfData

  Whether the visitor has opted out of the sale or sharing of their data with third parties. \`true\` means opted out, \`false\` means not opted out, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* type

  The type of consent change. Always \`'changeVisitorConsent'\`.

  ```ts
  'changeVisitorConsent'
  ```

### TrackingConsentMetafieldChange

* key

  The identifier for the tracking consent metafield to update.

  ```ts
  string
  ```

* value

  The new value to store in the metafield. Set to \`null\` to delete the metafield.

  ```ts
  string | null
  ```

### TrackingConsentChangeResult

The result returned by \`applyTrackingConsentChange\`. Either a \`TrackingConsentChangeResultSuccess\` if the consent preferences were saved, or a \`TrackingConsentChangeResultError\` if the update failed.

```ts
TrackingConsentChangeResultSuccess | TrackingConsentChangeResultError
```

### TrackingConsentChangeResultSuccess

Returned when the tracking consent update succeeds. Check the \`type\` property to confirm the result before proceeding.

* type

  The result type. Always \`'success'\` for a successful consent update.

  ```ts
  'success'
  ```

### TrackingConsentChangeResultError

Returned when the tracking consent update fails. Contains an error \`message\` with details about what went wrong.

* message

  A developer-facing message explaining why the consent update failed. This message isn't localized and shouldn't be displayed directly to the buyer.

  ```ts
  string
  ```

* type

  The result type. Always \`'error'\` for a failed consent update.

  ```ts
  'error'
  ```

### SubscribableSignalLike

Represents a reactive signal interface that provides both immediate value access and subscription-based updates. Enables real-time synchronization with changing data through the observer pattern. This interface extends \`ReadonlySignalLike\` with deprecated fields that are still supported for backwards compatibility.

* current

  The current value of the signal. Equivalent to \`.value\`, accessing this property subscribes to changes when used in a reactive context.

  ```ts
  T
  ```

* destroy

  Cleans up the subscription and releases any resources held by this signal. After calling \`destroy()\`, the signal stops receiving updates from the main thread.

  ```ts
  () => Promise<void>
  ```

* subscribe

  Subscribes to value changes and calls the provided function whenever the value updates. Returns an unsubscribe function to clean up the subscription. Use to automatically react to changes in the signal's value.

  ```ts
  (fn: (value: T) => void) => () => void
  ```

* value

  The current value of the signal. This property provides immediate access to the current value without requiring subscription setup. Use for one-time value checks or initial setup.

  ```ts
  T
  ```

### CustomerPrivacy

* allowedProcessing

  Flags indicating whether each type of data processing is permitted, based on the visitor's consent, the merchant's privacy configuration, and the visitor's geographic location.

  ```ts
  AllowedProcessing
  ```

* metafields

  The tracking consent metafields that have been stored for this visitor. These contain app-specific consent data beyond the standard categories.

  ```ts
  TrackingConsentMetafield[]
  ```

* region

  The visitor's geographic location, used to determine whether more granular consent controls should be displayed based on regional privacy regulations.

  ```ts
  CustomerPrivacyRegion
  ```

* saleOfDataRegion

  Whether the visitor is located in a region that requires an explicit opt-out option for the sale or sharing of personal data, such as California (CCPA) or other jurisdictions with similar regulations.

  ```ts
  boolean
  ```

* shouldShowBanner

  Whether a consent banner should be displayed when the page loads. This is determined by the visitor's current consent state, the merchant's \[region visibility settings]\(https://help.shopify.com/en/manual/privacy-and-security/privacy/customer-privacy-settings/privacy-settings#add-a-cookie-banner), and the visitor's geographic location. Use this as the initial visibility state for your consent banner UI.

  ```ts
  boolean
  ```

* visitorConsent

  The visitor's current privacy consent decisions for each category.

  ```ts
  VisitorConsent
  ```

### AllowedProcessing

* analytics

  Whether analytics data can be collected about how the buyer interacts with the shop, based on their consent, merchant configuration, and location.

  ```ts
  boolean
  ```

* marketing

  Whether marketing data can be collected for attribution, targeted advertising, and promotional communications.

  ```ts
  boolean
  ```

* preferences

  Whether preference data can be collected, such as the buyer's language, currency, and sizing choices.

  ```ts
  boolean
  ```

* saleOfData

  Whether data can be shared with or sold to third parties, typically for behavioral advertising purposes.

  ```ts
  boolean
  ```

### TrackingConsentMetafield

* key

  The identifier for the tracking consent metafield, such as \`'analyticsType'\` or \`'marketingType'\`.

  ```ts
  string
  ```

* value

  The value stored in the tracking consent metafield, such as \`'granular'\` or a stringified JSON object.

  ```ts
  string
  ```

### CustomerPrivacyRegion

* countryCode

  The buyer's country code in \[ISO 3166-1 alpha-2]\(https://en.wikipedia.org/wiki/ISO\_3166-1\_alpha-2) format. The value is \`undefined\` if geolocation failed. {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to \[protected customer data]\(/docs/apps/store/data-protection/protected-customer-data).

  ```ts
  CountryCode
  ```

* provinceCode

  The buyer's province, state, or region code in \[ISO 3166-2]\(https://en.wikipedia.org/wiki/ISO\_3166-2) format. The value is \`undefined\` if geolocation failed or only the country was detected. {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to \[protected customer data]\(/docs/apps/store/data-protection/protected-customer-data).

  ```ts
  string
  ```

### CountryCode

```ts
'AC' | 'AD' | 'AE' | 'AF' | 'AG' | 'AI' | 'AL' | 'AM' | 'AN' | 'AO' | 'AR' | 'AT' | 'AU' | 'AW' | 'AX' | 'AZ' | 'BA' | 'BB' | 'BD' | 'BE' | 'BF' | 'BG' | 'BH' | 'BI' | 'BJ' | 'BL' | 'BM' | 'BN' | 'BO' | 'BQ' | 'BR' | 'BS' | 'BT' | 'BV' | 'BW' | 'BY' | 'BZ' | 'CA' | 'CC' | 'CD' | 'CF' | 'CG' | 'CH' | 'CI' | 'CK' | 'CL' | 'CM' | 'CN' | 'CO' | 'CR' | 'CU' | 'CV' | 'CW' | 'CX' | 'CY' | 'CZ' | 'DE' | 'DJ' | 'DK' | 'DM' | 'DO' | 'DZ' | 'EC' | 'EE' | 'EG' | 'EH' | 'ER' | 'ES' | 'ET' | 'FI' | 'FJ' | 'FK' | 'FO' | 'FR' | 'GA' | 'GB' | 'GD' | 'GE' | 'GF' | 'GG' | 'GH' | 'GI' | 'GL' | 'GM' | 'GN' | 'GP' | 'GQ' | 'GR' | 'GS' | 'GT' | 'GW' | 'GY' | 'HK' | 'HM' | 'HN' | 'HR' | 'HT' | 'HU' | 'ID' | 'IE' | 'IL' | 'IM' | 'IN' | 'IO' | 'IQ' | 'IR' | 'IS' | 'IT' | 'JE' | 'JM' | 'JO' | 'JP' | 'KE' | 'KG' | 'KH' | 'KI' | 'KM' | 'KN' | 'KP' | 'KR' | 'KW' | 'KY' | 'KZ' | 'LA' | 'LB' | 'LC' | 'LI' | 'LK' | 'LR' | 'LS' | 'LT' | 'LU' | 'LV' | 'LY' | 'MA' | 'MC' | 'MD' | 'ME' | 'MF' | 'MG' | 'MK' | 'ML' | 'MM' | 'MN' | 'MO' | 'MQ' | 'MR' | 'MS' | 'MT' | 'MU' | 'MV' | 'MW' | 'MX' | 'MY' | 'MZ' | 'NA' | 'NC' | 'NE' | 'NF' | 'NG' | 'NI' | 'NL' | 'NO' | 'NP' | 'NR' | 'NU' | 'NZ' | 'OM' | 'PA' | 'PE' | 'PF' | 'PG' | 'PH' | 'PK' | 'PL' | 'PM' | 'PN' | 'PS' | 'PT' | 'PY' | 'QA' | 'RE' | 'RO' | 'RS' | 'RU' | 'RW' | 'SA' | 'SB' | 'SC' | 'SD' | 'SE' | 'SG' | 'SH' | 'SI' | 'SJ' | 'SK' | 'SL' | 'SM' | 'SN' | 'SO' | 'SR' | 'SS' | 'ST' | 'SV' | 'SX' | 'SY' | 'SZ' | 'TA' | 'TC' | 'TD' | 'TF' | 'TG' | 'TH' | 'TJ' | 'TK' | 'TL' | 'TM' | 'TN' | 'TO' | 'TR' | 'TT' | 'TV' | 'TW' | 'TZ' | 'UA' | 'UG' | 'UM' | 'US' | 'UY' | 'UZ' | 'VA' | 'VC' | 'VE' | 'VG' | 'VN' | 'VU' | 'WF' | 'WS' | 'XK' | 'YE' | 'YT' | 'ZA' | 'ZM' | 'ZW' | 'ZZ'
```

### VisitorConsent

* analytics

  Whether the visitor has consented to analytics tracking. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* marketing

  Whether the visitor has consented to marketing and targeted advertising. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* preferences

  Whether the visitor has consented to storing preferences such as language and currency. \`true\` means consent was granted, \`false\` means denied, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

* saleOfData

  Whether the visitor has opted out of the sale or sharing of their data with third parties. \`true\` means opted out, \`false\` means not opted out, and \`undefined\` means no decision has been made.

  ```ts
  boolean
  ```

### Examples

* #### Display a consent banner

  ##### Description

  Check whether to show a cookie consent banner and allow the buyer to accept or decline tracking. This example reads \`shopify.customerPrivacy.shouldShowBanner\` and renders accept/decline buttons that call \`shopify.applyTrackingConsentChange\`.

  ##### jsx

  ```jsx
  import '@shopify/ui-extensions/preact';
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  function Extension() {
    const {shouldShowBanner} =
      shopify.customerPrivacy.value;

    if (!shouldShowBanner) {
      return null;
    }

    async function acceptAll() {
      await shopify.applyTrackingConsentChange({
        type: 'changeVisitorConsent',
        analytics: true,
        marketing: true,
        preferences: true,
        saleOfData: false,
      });
    }

    async function declineAll() {
      await shopify.applyTrackingConsentChange({
        type: 'changeVisitorConsent',
        analytics: false,
        marketing: false,
        preferences: false,
        saleOfData: true,
      });
    }

    return (
      <s-banner tone="info">
        <s-stack direction="block" gap="small-200">
          <s-text>
            We use cookies to improve your
            experience. Choose your preferences.
          </s-text>
          <s-stack direction="inline" gap="base">
            <s-button onClick={acceptAll}>
              Accept all
            </s-button>
            <s-button
              variant="secondary"
              onClick={declineAll}
            >
              Decline all
            </s-button>
          </s-stack>
        </s-stack>
      </s-banner>
    );
  }
  ```

* #### Read the current consent state

  ##### Description

  Display the buyer's current consent preferences for each tracking category. This example reads \`shopify.customerPrivacy\` and renders the status of analytics, marketing, preferences, and sale of data consent.

  ##### jsx

  ```jsx
  import '@shopify/ui-extensions/preact';
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  function consentLabel(value) {
    if (value === true) return 'Granted';
    if (value === false) return 'Denied';
    return 'No decision';
  }

  function saleOfDataLabel(value) {
    if (value === true) return 'Opted out';
    if (value === false) return 'Not opted out';
    return 'No decision';
  }

  function Extension() {
    const {visitorConsent} =
      shopify.customerPrivacy.value;

    const categories = [
      {label: 'Analytics', display: consentLabel(visitorConsent?.analytics)},
      {label: 'Marketing', display: consentLabel(visitorConsent?.marketing)},
      {label: 'Preferences', display: consentLabel(visitorConsent?.preferences)},
      {label: 'Sale of data', display: saleOfDataLabel(visitorConsent?.saleOfData)},
    ];

    return (
      <s-box padding="base">
        <s-stack direction="block" gap="small-200">
          <s-text type="strong">
            Privacy Consent Status
          </s-text>
          {categories.map((category) => (
            <s-stack
              key={category.label}
              direction="inline"
              gap="base"
            >
              <s-text type="strong">
                {category.label}:
              </s-text>
              <s-text>
                {category.display}
              </s-text>
            </s-stack>
          ))}
        </s-stack>
      </s-box>
    );
  }
  ```

* #### Apply consent changes

  ##### Description

  Save updated tracking consent preferences after the buyer interacts with your consent UI. This example calls \`shopify.applyTrackingConsentChange\` with the buyer's selections and displays a success or error message based on the result.

  ##### jsx

  ```jsx
  import '@shopify/ui-extensions/preact';
  import {render} from 'preact';
  import {useState} from 'preact/hooks';

  export default async () => {
    render(<Extension />, document.body);
  };

  function Extension() {
    const [status, setStatus] = useState('');

    async function grantAnalyticsOnly() {
      try {
        const result =
          await shopify.applyTrackingConsentChange({
            type: 'changeVisitorConsent',
            analytics: true,
            marketing: false,
            preferences: false,
            saleOfData: true,
          });

        if (result.type === 'success') {
          setStatus('Preferences saved.');
        } else {
          setStatus('Failed to save preferences.');
        }
      } catch (error) {
        setStatus('An error occurred.');
      }
    }

    return (
      <s-box padding="base">
        <s-stack direction="block" gap="small-200">
          <s-text type="strong">
            Cookie Preferences
          </s-text>
          <s-text>
            Allow only essential cookies and
            analytics to help us improve your
            experience.
          </s-text>
          <s-button onClick={grantAnalyticsOnly}>
            Save preferences
          </s-button>
          {status && (
            <s-text color="subdued">
              {status}
            </s-text>
          )}
        </s-stack>
      </s-box>
    );
  }
  ```

***

## Best practices

* **Use `shouldShowBanner` for initial state**: Check the `shouldShowBanner` property to determine whether to display a consent banner when the page loads, rather than always showing one.
* **Respect regional requirements**: Use `saleOfDataRegion` and `region` to determine if additional opt-out controls are required for the buyer's location.

***
