--- title: Enable extension capabilities for checkout description: >- Learn how to configure Storefront API access, network access, block progress, and buyer consent collection for checkout UI extensions. source_url: html: 'https://shopify.dev/docs/apps/build/checkout/capabilities' md: 'https://shopify.dev/docs/apps/build/checkout/capabilities.md' --- # Enable extension capabilities for checkout Capabilities are permissions you declare in your extension's [`shopify.extension.toml`](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions) file. They control what your extension is allowed to do at a platform level, such as querying the Storefront API, making external network calls, or collecting buyer consent. *** ## Available capabilities | Property | Description | | - | - | | [`api_access`](#storefront-api-access) | Allows your extension to query the [Storefront API](https://shopify.dev/docs/api/storefront). | | [`network_access`](#network-access) | Allows your extension to make external network calls. | | [`block_progress`](#block-progress) | Allows your extension to block the buyer's progress. | | [`collect_buyer_consent`](#collect-buyer-consent) | Allows your extension to collect buyer consent for specific policies. | The following example shows a complete `shopify.extension.toml` file with all four capabilities enabled: ## Capabilities ## shopify.extension.toml ```toml # ... [extensions.capabilities] api_access = true network_access = true block_progress = true [extensions.capabilities.collect_buyer_consent] sms_marketing = true customer_privacy = true # ... ``` *** ## Storefront API access The following section describes the use cases of the `api_access` capability and the [Storefront API](https://shopify.dev/api/storefront) access scopes. [See - API access examples](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/storefront-api) ### When to use Storefront API access API access is used when your extension needs to retrieve data from the [Storefront API](https://shopify.dev/api/storefront). For example, you may need to [fetch product data](https://shopify.dev/apps/checkout/product-offers/add-product-offer), check the product tags on an item in the cart, or convert a product's price to another currency. **Tip:** Shopify handles the authentication for all API calls from an extension. ### Methods for accessing the Storefront API Enabling the `api_access` capability allows you to use the checkout [Storefront API](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/storefront-api#docsstandardqueryapi-propertydetail-query) `query` method and the global `fetch` to retrieve data from the Storefront API without manually managing token acquisition and refresh. `query` lets you request a single GraphQL response from the Storefront API. If you prefer to construct GraphQL requests yourself or you would like to use a full-featured GraphQL client such as Apollo or urql, our custom `fetch` global automatically appends the required access tokens. The GraphQL client of your choice shouldn’t use any DOM APIs, as they aren’t available in a checkout UI extension's Web Worker. **Note:** Both `query` and `fetch` will work for calling the Storefront API with the `api_access` capability enabled. If you are using `fetch` to get data external to Shopify, refer to the [`network_access`](#network-access) capability. ### Storefront API access scopes Your extensions will have the following unauthenticated access scopes to the Storefront API: * `unauthenticated_read_product_publications` * `unauthenticated_read_collection_publications` * `unauthenticated_read_product_listings` * `unauthenticated_read_product_tags` * `unauthenticated_read_selling_plans` * `unauthenticated_read_collection_listings` * `unauthenticated_read_metaobjects` ### Protocol Links Protocol links are an easy way for Shopify to infer the type of request you are trying to make. If you would like to make a request to the [Storefront GraphQL API](https://shopify.dev/docs/api/storefront), you can use our [Storefront Protocol](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/storefront-api) to infer your Storefront URL and API version. ## Enable Storefront API access ## shopify.extension.toml ```toml # ... [extensions.capabilities] api_access = true # ... ``` *** ## Network access The following section describes use cases for requesting network access, alternatives to requesting network access, and steps for completing a request for network access. **Caution:** If your extension specifies the `network_access` capability, you must request access in order to publish your extension. ### When to request network access If you need to get data into checkout that you can't currently get from Shopify, then you should request network access. For example, you might need to fetch additional data to render loyalty points. ### Alternatives to network access Instead of fetching data with an external network call, consider retrieving the data from a metafield. Your app may be able to use the [GraphQL Admin API](https://shopify.dev/docs/api/admin) to write [metafields](https://shopify.dev/api/admin-graphql/latest/objects/metafield) on the shop, product, or customer ahead of checkout. Retrieving data from [metafields](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/metafields-api) during checkout is faster since it won't introduce an external network call. This allows you to rely on Shopify for the uptime, scaling, and durability of the data storage. ### Complete a request for network access 1. Go to your [Partner Dashboard](https://partners.shopify.com/current/apps). 2. Click the name of the app that you want to change. 3. Click **API access**. 4. Under **Allow network access in checkout UI extensions**, click **Allow network access** Your request is automatically approved and your app is immediately granted the approval scope that's required for your checkout UI extension to make external network calls. 5. Add `network_access = true` to the `[extensions.capabilities]` section of your extension's configuration file. ### Required CORS headers UI extensions run in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) but the exact origin they run on may change without notice. When receiving network requests from extensions, your server must support [cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for any origin by always returning this response header: `Access-Control-Allow-Origin: *` ### Security considerations When processing HTTP requests on your API server, you cannot guarantee that your own extension will have made every request. When responding with sensitive data, keep in mind that requests could originate from anywhere on the Internet. Your extension can pass a [session token](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/session-token-api) to your API server but this only guarantees the integrity of its claims. It does not guarantee the request itself originated from Shopify. For example, your API server could trust the session token's `sub` claim (the customer ID) but it could not trust a `?customer_id=` query parameter. Consider a scenario where your extension retrieves a discount code from your API server and [applies it to the checkout](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/discounts-api#docscheckoutdiscountsapi-propertydetail-applydiscountcodechange). It would not be safe to expose an API endpoint named `/get-discount-code` if any buyer could make a direct HTTP request and obtain a discount code. ### App Proxy UI extensions can make fetch requests to [App Proxy](https://shopify.dev/docs/apps/online-store/app-proxies) URLs, but there are some differences and limitations related to the security context within which UI extensions run. UI extension requests made to the App Proxy will execute as CORS requests. See *Required CORS headers* above for information about requirements related to CORS. UI extension requests made to the App Proxy will not assign the `logged_in_customer_id` query parameter. Instead use a [session token](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/session-token-api) which provides the `sub` claim for the logged in customer. UI extension requests made to the App Proxy of password protected shops is not supported. Extension requests come from a web worker which does not share the same session as the parent window. The App Proxy doesn't handle all [HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods). Specifically, `CONNECT` and `TRACE` are unsupported. ## Enable network access ## shopify.extension.toml ```toml # ... [extensions.capabilities] network_access = true # ... ``` *** ## Block progress The following section describes blocking the buyer's progress through checkout, and how you can detect whether the merchant has allowed it. [See - Blocking examples](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/buyer-journey-api?example=block-progress-at-the-page-level) ### When to request blocking progress If your extension relies on specific input then you might need to block the buyer's progress until they've provided all required information. You can do this with a [buyer journey](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/buyer-journey-api) intercept, by returning `behavior: 'block'`. For example, for some purchases you need to collect and verify a customer's age. For the order to be valid, you need to verify that an age is set and that it's greater than or equal to a minimum value. In order to block checkout progress, your extension must have the `block_progress` capability. ### Granting the capability to block progress Setting `block_progress` in the `shopify.extension.toml` file informs merchants that your extension blocks the buyer's progress for invalid orders. Merchants can allow or disallow this capability in the checkout editor. **Note:** When running a local extension with the `block_progress` capability, it will be automatically granted. This simulates a scenario where the merchant has allowed the capability. ### Detecting the ability to block progress In your extension, look for `block_progress` in [`extension.capabilities`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/extension-api) to see if the merchant has granted the blocking capability. If the merchant declined the permission for your app to block progress, the `behavior: 'block'` option in the [buyer journey](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/buyer-journey-api) intercept will be treated as `behavior: 'allow'`, and checkout will proceed as normal. When developing a local extension, you can remove the `block_progress` capability from your `shopify.extension.toml` file to simulate a merchant disallowing the capability. **Tip:** We recommend having some UI to cover cases where you can't block checkout progress. For example, you might want to show a warning rather than block checkout progress when an order doesn't pass validation. ## Enable progress blocking ## shopify.extension.toml ```toml # ... [extensions.capabilities] block_progress = true # ... ``` *** ## Collect buyer consent Use the `collect_buyer_consent` capability when your extension applies consent changes. This capability is required before your extension can call [`applyTrackingConsentChange()`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/customer-privacy-api) or use the [consent checkbox](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/consent-checkbox) and [consent phone field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/consent-phone-field) components. Reading consent state from `shopify.customerPrivacy` does not require this capability. Shopify manages a consent state for each visitor that tracks preferences across categories, including analytics, marketing, preferences, and sale of data. When you enable `collect_buyer_consent`, your extension can participate in this system by reading the current consent state and applying updates. ### How consent state works Shopify tracks each visitor's consent decisions for analytics, marketing, preferences, and data sale. When a visitor hasn't made a decision yet, your extension can present a consent banner and record their choices. Read the current state from `shopify.customerPrivacy.value`: * **`saleOfDataRegion`**: Set to `true` when the visitor's region requires sale-of-data opt-out controls. * **`shouldShowBanner`**: Set to `true` when the visitor hasn't made a consent decision yet. Check this before rendering a banner. * **`visitorConsent`**: The visitor's current choices for `analytics`, `marketing`, `preferences`, and `saleOfData`. Save the visitor's choices with `shopify.applyTrackingConsentChange()`. Shopify applies these decisions across all Shopify-managed services. []() ### SMS marketing consent Add `sms_marketing = true` to use the [consent checkbox](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/consent-checkbox) and [consent phone field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/consent-phone-field) components. Set the `policy` attribute to `sms-marketing` on those components. []() ### Customer privacy consent Add `customer_privacy = true` to use the [Customer Privacy API](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/customer-privacy-api) for collecting cookie and tracking consent. ### Enable consent collection ## shopify.extension.toml ```toml [extensions.capabilities.collect_buyer_consent] customer_privacy = true sms_marketing = true ``` [Reference - Customer Privacy API](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/customer-privacy-api) ***