The apple-app-site-association file explained

How the apple-app-site-association file works, where to host it, its JSON structure, app IDs, components rules and how to test universal links with swcutil.

Short answer: The apple-app-site-association (AASA) file tells iOS which of your app's URLs should open the app. It lives at https://<domain>/.well-known/apple-app-site-association, has no file extension, must be served over HTTPS with no redirects, and lists app IDs and URL patterns under applinks. Test yours with curl -I on the file URL and swcutil on a Mac.

What is an apple-app-site-association file?

apple-app-site-association (AASA): a JSON file hosted on your domain that lists which iOS apps may open which URLs on that domain as universal links, and which apps may use the domain for shared web credentials and App Clips.

iOS reads it alongside your app's Associated Domains entitlement. Both halves must agree: the entitlement claims the domain, and the file on the domain names the app. Since iOS 14 and macOS 11, devices fetch the file from an Apple-managed CDN, which in turn fetches it from your server.

How is the file structured?

The root is an object. For universal links, the key that matters is applinks, which holds a details array. Each entry pairs a list of apps with the URL patterns they handle.

{
  "applinks": {
    "defaults": { "caseSensitive": false },
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.app", "ABCDE12345.com.example.app2"],
        "components": [
          { "#": "no_universal_links", "exclude": true, "comment": "Opt-out fragment" },
          { "/": "/buy/*" },
          { "/": "/help/website/*", "exclude": true },
          { "/": "/help/*", "?": { "articleNumber": "????" } }
        ]
      }
    ]
  },
  "webcredentials": { "apps": ["ABCDE12345.com.example.app"] },
  "appclips": { "apps": ["ABCDE12345.com.example.MyApp.Clip"] }
}
  • appIDs: each value is <Application Identifier Prefix>.<Bundle Identifier>, for example ABCDE12345.com.example.app.
  • components: an array of pattern objects, checked in order.
  • defaults: global matching settings for every rule on the domain (iOS 14 and later).
  • substitutionVariables: named lists of strings that patterns can reuse. Apple provides built-ins such as lang and region.
  • webcredentials and appclips: use an apps array. Apple notes the details dictionary "only applies to the applinks service type".

Components versus legacy paths

Apple has used two formats for rules. The current one is appIDs plus components, introduced with iOS 13 according to Apple's documentation metadata. The legacy one is appID (a string) plus paths (an array of strings, with NOT as an exclusion prefix).

KeyMatchesDefault
/URL path*
?Query, as a pattern or a dictionary of parameters*
#Fragment*
excludeStops matching and keeps the URL on the webfalse
caseSensitiveCase of the patterntrue
percentEncodedWhether patterns are percent-encodedtrue
commentIgnored text for notesnone

Apple's advice on the two formats: "Please avoid mixing formats. Doing so may result in unexpected behavior." Use one format per file.

How does iOS decide which rule applies?

iOS checks rules in array order and stops at the first match. Apple says: "The order that you use to specify the patterns in the array determines the order the system follows when looking for a match. The first match wins."

  • Put exclude rules above the broader rules they carve out.
  • A URL must match every key a rule specifies. {"/":"abc","?":"def"} matches /abc?def but not /abc alone.
  • * matches zero or more characters, ? matches exactly one, and ?* matches one or more.

Run sudo swcutil verify on a Mac to see whether a URL matches your rules. If the wrong rule wins, see path not matched.

Where do you host the file?

  • At https://<fully qualified domain>/.well-known/apple-app-site-association, with no extension.
  • Over HTTPS "with a valid certificate and with no redirects".
  • On every domain in the entitlement. Each subdomain "must serve its own apple-app-site-association file", although applinks:*.example.com uses the file at the apex.
  • Open to "all geographical locations, from any IP address" and all user agents, so Apple's CDN can fetch it.
  • As plain JSON. Apple's archived guide describes application/json, which is also what Apple's CDN returns.
  • Under 128 KB uncompressed, the limit in Apple's archived documentation for iOS 9.3.1 and later.

Apple's archived Handoff guide mentions a fallback to the domain root, but current documentation only describes /.well-known/, and developer mode requires it. Host it there.

How do you test the file?

Test the file content and how your server delivers it:

  1. curl -I https://example.com/.well-known/apple-app-site-association for a 200 and no redirect, then curl -v on the same URL to see the JSON body.
  2. curl -A "MyAgent-Bot/*" https://example.com/.well-known/apple-app-site-association, Apple's suggested user-agent check.
  3. On a Mac: sudo swcutil dl -d example.com, then sudo swcutil verify -d example.com -j apple-app-site-association -u https://example.com/buy/1.
  4. On a device with Developer Mode on: Settings > Developer > Universal Links > Diagnostics.
  5. Paste a link into Notes, tap it, then long-press it to see both the app and browser options.

Apple's CDN fetches the file within 24 hours and devices check about once a week after install, so reinstall the app on test devices after each change, or use applinks:example.com?mode=developer while iterating. For the app side, see the universal links setup guide.

FAQ

Common questions

Does the AASA file need a .json extension?

No. Apple's documentation says the file is named `apple-app-site-association` without an extension. It still contains JSON and should be served as JSON.

What is the size limit for an AASA file?

Apple's archived documentation sets 128 KB uncompressed for iOS 9.3.1 and later. Current pages do not restate it, but staying under it is easy with wildcard rules.

Can I use the old paths format?

Apple still describes `appID` and `paths` in its debugging technote, but warns against mixing them with `components`. For new files, use `appIDs` and `components`.

Why is my file fine but links still fail?

A correct file is only one part. Redirects, blocked access, Apple's CDN cache, typed links and in-app browsers all happen outside the file, so work through the [developer notes](/developers/) for those.

How do I check what Apple's CDN has cached?

Apple's own tools are `swcutil` on a Mac and the Diagnostics screen on a device in Developer Mode. Reinstalling the app on a test device makes it download the current copy from the CDN.

What are UTM parameters?

UTM parameters are tags added to the end of a link, such as utm_source and utm_campaign, that tell analytics tools where a visit came from. They let you see which campaign, channel and ad brought each visitor.