Instead of reading return policy text, apps can now fetch rules such as the return window for each market through the API. Profiles take precedence over the store's return policy text. They're read-only through the API.
Shop.shopPolicies 's REFUND_POLICY and similar fields were the only way to read return conditions, as plain text.
You can retrieve each market's return rules field by field. To set different return rules for different markets, you need to use profiles.
A profile is the unit for configuring return rules, and it's what markets are linked to.
Editing a profile changes the return terms for every market that references it.
It's locked so return terms never fall below the minimum standard. Apps can read it but can't assign it to other markets.
| Type | Name | Description |
|---|---|---|
| Query | returnPolicyProfile |
Returns a single profile by ID |
| Query | returnPolicyProfiles |
Returns the store's list of profiles.default An argument lets you filter by whether a profile is the default |
| Field | Market.returnPolicyProfile |
The profile directly assigned to the market (null if none) |
| Mutation input | marketCreate / marketUpdate |
Assigns a profile when creating or updating a market. Updates can also remove the assignment (see each reference for input fields) |
read_legal_policiesRequired to read profiles (includingMarket 's returnPolicyProfile field).
write_marketsAssigning or unassigning a profile to a market counts as editing the market.
Market.returnPolicyProfile is nullMeans no profile is directly assigned to that market. The market hierarchy is not resolved.
returnRules / editRules is nullThis doesn't mean missing data โ it means the rule is OFF .returnRules is null in a profile, customers can make returns without restrictions.
updatedAt is an aggregate valueIt isn't a value stored on the profile row itself; it's aggregated across the profile and all its rules. It advances whenever any part of the policy changes.
โ Specifying both assign and unassign in the same market update request โก Assigning a Shopify-provided Managed Markets profile to a market.
Existing queries that read the policy body keep working as-is.
Shop.shopPolicies 's REFUND_POLICY : if you read return conditions from it, move to returnPolicyProfiles instead.
To represent return rules that differ by market, you need to use profiles.
Market.returnPolicyProfile null means "no direct assignment."returnRules null means "rule OFF = returns allowed without restrictions." Treating either as "no data" leads to incorrect display.
The API doesn't resolve the market hierarchy. Since unassigned markets fall back to the default profile, to show the effective rule, use returnPolicyProfiles(default: ...) to fetch the default and fill the gap.
updatedAt as the keyIt's an aggregate that advances even when rules under the profile change, so it works as a change-detection key. Also keep in mind that editing a profile affects every market that references it.
Profile CRUD is admin-only. All an app can do is use marketCreate / marketUpdate to assign and unassign (write_markets).
the same marketUpdate โ don't send assignments and unassignments together. Exclude Managed Markets' locked EU profiles from the assignment options in your UI.
REFUND_POLICY text or custom settings, so it can't reflect return conditions that differ by market.returnPolicyProfiles and Market.returnPolicyProfile to fetch each market's rules and use them to decide whether a return is eligible.read_legal_policies is required.returnRules is null, treat it as "no limit." For markets with no direct assignment (null), fall back to the default profile.marketCreate / marketUpdate to assign the relevant profile.write_markets is required. Don't mix assignments and unassignments in the same request. Managed Markets EU profiles can't be assigned (user error), so exclude them from the options.updatedAt changes.updatedAt is an aggregate value that also advances on rule changes, so it works as a change-detection key. Webhooks aren't mentioned.