App Store External Purchase Links in 2026: A Step-by-Step Tutorial for Entitlements, Info.plist Keys, and Token Reporting
App Review Guideline 3.1.1 still requires digital goods and services sold inside an App Store app to use in-app purchase — but the list of carve-outs grew again, and in 2026 there are three different ways a compliant app can send a customer to a payment page of its own. The current text of guideline 3.1.1(a) says it plainly: developers may apply for entitlements to provide a link in their app to a website they own or maintain responsibility for, and — the sentence that matters most to US publishers — “These entitlements are not required for developers to include buttons, external links, or other calls to action in their United States storefront apps.” In every other storefront, the same guideline says apps and their metadata may not include buttons, external links, or other calls to action that direct customers to purchasing mechanisms other than in-app purchase.
The one-line version: the United States storefront needs no entitlement at all; the com.apple.developer.storekit.external-purchase-link entitlement covers the iOS/iPadOS storefronts where Apple permits a link-out; and the newer custom purchase link entitlement is region-scoped, with Brazil and Japan joining the EU country codes. ExternalPurchaseLink tells you at runtime whether any of it applies, eligibleURLs and open(url:) actually open the link, and every token that comes back has to be reported through the External Purchase Server API.
Step 1 — Work out which of the three routes your app is on
Route one is the US storefront: link-outs are allowed without an entitlement, and the guideline explicitly says so. Route two is com.apple.developer.storekit.external-purchase-link, also known as the StoreKit External Purchase Link entitlement — Apple's own summary is that it “enables qualifying apps to include a link that directs people using the app to a website to make an external purchase,” and the entitlement agreement limits that link to informing people where and how to purchase in-app items, including the fact that they may be available at a comparatively lower price. Route three is com.apple.developer.storekit.custom-purchase-link.allowed-regions: an entitlement that “enables a qualifying app to offer external purchases within app or at a website, in specific regions,” and whose value is not a boolean but an array of two-letter ISO-3166-1 codes. As documented, permitted custom purchase link regions include Brazil (br), Japan (jp) and the EU country codes — Austria, Belgium, Bulgaria, Croatia, Cyprus, Czechia, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain and Sweden.
Before writing any code, list the storefronts you actually ship in. A single global link that ignores the storefront boundary is the most common way this feature turns into a rejection.
Step 2 — Get the entitlement onto your signing profile
Entitlements are granted per developer account, not per app store listing, and Apple states the limitation directly: the entitlements “are limited to use only in the iOS or iPadOS App Store in specific storefronts.” Once the account receives the StoreKit External Purchase Link entitlement, you add it to your app by opening the project's .entitlements file in Xcode, adding the key com.apple.developer.storekit.external-purchase-link and setting its value to true. For the region-scoped variant, the key is com.apple.developer.storekit.custom-purchase-link.allowed-regions and the value is an array of the lowercase country codes where you intend to offer the functionality — Apple's wording is that it “must only include regions where Apple supports custom purchase link options.”
Because an entitlement is tied to the provisioning profile, the practical sequence is: request, wait for the capability to appear, regenerate profiles, re-sign, then upload. A build signed with an old profile simply will not be able to open the link, and the failure shows up at runtime rather than at build time.
Step 3 — Configure the destination URLs in Info.plist
Two property list keys do the work, and picking the right one decides which API you call. SKExternalPurchaseLink is a dictionary whose keys are lowercased ISO 3166-1 alpha-2 country codes — one destination URL per country code. Apple lists the valid codes: the twenty-seven EU member states plus Iceland (is), Norway (no) and Russia (ru). SKExternalPurchaseMultiLink is the multi-link variant: the same dictionary shape, but each country code maps to an array of one to five destination URLs.
Every destination URL has to satisfy four conditions, and the fourth is the one people miss: it must use the HTTPS scheme, form a valid absolute URL, contain no query parameters, and be 1,000 or fewer ASCII characters. On top of that, Apple states that “At all times, the destination URLs that you provide in the property list key must match the values in your app binary that you submit to App Review” — so the URLs are effectively part of your review submission, and changing them is a release, not a config edit.
MultiLink is not available to everyone: you can provide one or more links per country code if your app qualifies for the StoreKit External Purchase Link entitlement as Apple describes it; otherwise you provide exactly one link per country code.
Step 4 — Gate the UI with canOpen before you draw anything
canOpen is a boolean that answers “can this app successfully open the configured external purchase link in the current App Store storefront?” Apple documents exactly three conditions that must all hold: the current storefront allows external purchase and the person is eligible to make external purchases; your app configures the com.apple.developer.storekit.custom-purchase-link.allowed-regions or com.apple.developer.storekit.external-purchase-link entitlement; and your app configures a link for the current storefront. Anything else is false. There is no need to re-check it unless the App Store storefront changes, which means you can evaluate it once on launch and drive your paywall UI from the result. When it is false, the documented fallback is to check canMakePayments and stay on in-app purchase.
Step 5 — Open the link: open() or open(url:)
With a single configured link, call ExternalPurchaseLink.open(). With the multi-link key, read eligibleURLs — the array of links the app configured for the current storefront — and call open(url:) with the one you choose, in response to deliberate user interaction such as tapping a button. Apple is explicit that eligibleURLs comes back nil in three situations: the storefront does not allow external purchase or the person is ineligible; the entitlement is missing; or no links are configured for the current storefront. Nil plus a configured SKExternalPurchaseLink means fall back to canOpen; nil without one means fall back to canMakePayments.
open(url:) is asynchronous and presents a continuation sheet that lets the person choose whether the app shows the external purchase link. It returns before the sheet is presented and can throw a StoreKitError when the entitlement is absent, no link is configured for the storefront, the storefront does not support external purchases, the person is ineligible, or a network or system error occurs. If the person chooses to continue, StoreKit opens your URL in the default browser and appends an external purchase token and the app's bundle ID to it — that token is the whole reason the reporting step exists.
Step 6 — Report every token through the External Purchase Server API
The External Purchase Server API is a REST API you call from your own server to “report external purchase tokens and your customers' transactions related to the tokens.” The instruction is not optional and it is not limited to successful sales: report all tokens, including those that did not result in a transaction. Concretely, Apple lists four cases that each require a report — a token with line items when a customer completes one or more transactions; a token without line items when the customer completes none; an unrecognized token, when an App Store Server Notification arrives for a token you have no record of; and duplicate ACQUISITION and SERVICES tokens. Authorisation uses JSON Web Tokens built from API keys you create in App Store Connect.
If you already run App Store Server Notifications V2, the reporting pipeline is the natural place to hook in: the notification tells you a token exists, your store records the transaction, and the External Purchase Server API report closes the loop.
Step 7 — Keep the storefront boundary in view
Everything above is bounded by one sentence repeated in the guideline and the entitlement: entitlements are limited to the iOS or iPadOS App Store in specific storefronts, and outside the United States storefront the app and its metadata may not include buttons, external links or other calls to action that direct customers to purchase mechanisms other than in-app purchase. That boundary applies to metadata too — a screenshot showing an external checkout in a storefront where links are not permitted is a rejection risk, not a marketing choice.
Pitfalls worth a second read
- Query parameters are banned. Tracking parameters on the destination URL break the documented URL rules; the token StoreKit appends is what carries attribution.
- The entitlement is a signing capability, not a server setting. Adding the key to
.entitlementswithout the granted capability produces a profile that cannot use it. - URLs must match the binary at all times. Drafting a new destination URL without a release is a mismatch Apple documents as a requirement, not a preference.
- One link per country unless you qualify for MultiLink. A five-URL array in a storefront where only one link is allowed is a review problem.
- US-only apps need nothing. If your listings are US-only, guideline 3.1.1(a) already permits the link-out — do not create a profile capability you do not need.
Where to start
Write down your storefront list, mark each one as US, entitlement-region, custom-purchase-link region or none, then implement the gate once: check canOpen (or eligibleURLs for multi-link), show the control only when it returns true, and leave in-app purchase as the default path for everyone else. The token plumbing on your server is the part that decides whether the feature stays compliant after launch.
Running developer accounts at scale? We handle the operational side.
We received your message and will reply within 24 hours.
Or email expert@kapps.store← Back to edit