Skip to main content

Target buyers by country instead of market ID

If your app uses any of the deprecated single-market endpoints listed below, this guide explains why they're deprecated, what can go wrong, and how to switch to country-based matching.


Anchor to Deprecated single-market endpointsDeprecated single-market endpoints

The deprecated single-market endpoints are market objects with single market identifiers such as id, name, handle, and regions. These endpoints only surface country-based markets:


Anchor to Why single-market endpoints are deprecatedWhy single-market endpoints are deprecated

Before market inheritance was introduced, a buyer belonged to exactly one market, so apps could safely use market.id or market.handle to decide what experience to show (for example, "if the market is North America, show this banner").

Now, merchants can create child markets (for example, a Canada market under North America). A Canadian buyer matches both markets. The deprecated single-market endpoints only return the most specific one (Canada), not the parent (North America).

If an app was configured to target the "North America" market by ID, Canadian buyers stop matching because the API now returns "Canada" instead. And it happens every time a merchant creates a new child market, forcing merchants to reconfigure the app each time.

TL;DR: Market IDs are no longer stable identifiers for targeting buyers.


Anchor to How to target buyers by countryHow to target buyers by country

Instead of matching buyers by market ID, you can match them by country code. Your app can still let merchants select from a list of markets in the UI — the difference is that you store the market's country codes instead of its ID. This guide shows you how to query a market's regions, store the country codes, and match buyers against them — so your app stays resilient regardless of how merchants organize their market hierarchy.



Anchor to Step 1: Query market regionsStep 1: Query market regions

Use market.conditions.regionsCondition.regions to resolve a market's country codes. Only include regions from active markets (enabled: true) — draft markets (enabled: false) aren't serving buyers. To list all markets on a store, use the markets query.

POST https://{shop}.myshopify.com/admin/api/{api_version}/graphql.json

GraphQL query

query {
market(id: "gid://shopify/Market/26429947989") {
id
name
enabled
conditions {
regionsCondition {
regions(first: 250) {
nodes {
... on MarketRegionCountry {
code
}
}
}
}
}
}
}

JSON response

{
"data": {
"market": {
"id": "gid://shopify/Market/26429947989",
"name": "North America Market",
"enabled": true,
"conditions": {
"regionsCondition": {
"regions": {
"nodes": [
{ "code": "CA" },
{ "code": "US" },
{ "code": "MX" }
]
}
}
}
}
}
}
Note

The MarketRegionCountry fragment in the query above already filters out subdivision markets, which operate at the province or state level. Neither the deprecated single-market endpoints nor the country-based approach in this guide targets subdivision markets.


Anchor to Step 2: Store regions per marketStep 2: Store regions per market

When a merchant selects markets in your app, resolve each active market's regions and persist a mapping of market ID to country codes. For example, if the merchant selects the North America market (gid://shopify/Market/26429947989) with CA, MX, and US regions:

{
"gid://shopify/Market/26429947989": ["CA", "MX", "US"]
}

Store this data in an app-owned metafield or a metaobject so it's exposable to your storefront or extension context. Alternatively, expose it through an app endpoint that the extension reads at render time.

Storing the market ID alongside the country codes lets you re-fetch or remove the correct entry when a markets/update or markets/delete webhook fires. At match time, flatten all values into a single set of country codes.


Anchor to Step 3: Match buyers by countryStep 3: Match buyers by country

Match the buyer's country against your stored regions. If your matching logic runs in a storefront or extension context, read the country codes from the metafield or app endpoint you set up in Step 2.

Before and after

Before (deprecated)

// Brittle: breaks when child markets are created
const naBannerMarketHandles = ["north_america"];
if (naBannerMarketHandles.includes(localization.market.handle)) {
renderNaBanner();
}

After (region-based)

// Resilient: matches any buyer in the target countries
const naBannerRegions = {
"gid://shopify/Market/26429947989": ["CA", "MX", "US"],
};
const naBannerCountries = new Set(Object.values(naBannerRegions).flat());
if (naBannerCountries.has(localization.country.isoCode)) {
renderNaBanner();
}

The following table lists the deprecated endpoints and their region-based replacements for each API surface:

Note: MarketWebPresence.markets returns a list of markets, not a country code.


Anchor to Step 4: Keep regions in sync with webhooksStep 4: Keep regions in sync with webhooks

When a merchant updates or deletes a market, your stored regions can become stale. Subscribe to both webhook topics in your app configuration file:

[webhooks]
api_version = "2026-07"

[[webhooks.subscriptions]]
uri = "/webhooks/markets/update"
topics = [ "markets/update" ]

[[webhooks.subscriptions]]
uri = "/webhooks/markets/delete"
topics = [ "markets/delete" ]
  • markets/update: Fires when a market's configuration changes, for example, when a country is added or removed or when the market's status changes between active and draft. Re-fetch the market's regions and status, and update your stored list of country codes. Only include countries from active markets.
  • markets/delete: Fires when a market is deleted. Remove the deleted market's reference from your stored data and recompute the list of country codes from any remaining markets.

A markets/create subscription isn't needed. New markets are picked up when the merchant selects them in Step 2, and country-based matching stays resilient until then.

See the webhooks reference for full details on these topics.

Caution

Without the markets/delete webhook, a deleted market's country codes persist indefinitely and your app continues targeting buyers it should no longer match.


Was this page helpful?