AASA file has the wrong structure

Your AASA file parses but universal links still fail. Fix the applinks, details, appIDs and components structure Apple expects, with a correct example.

SymptomThe AASA file parses as JSON but universal links still never open the app.
Likely causeThe keys are not where iOS expects them, for example a top-level array, a missing details array, or mixed legacy and current formats.
FixRebuild the file as an object with applinks, a details array and appIDs plus components in each entry.

Short answer: Valid JSON is not enough. iOS expects a top-level object with an applinks key, a details array inside it, and each entry holding appIDs and components. If keys are misnamed, nested wrongly or mixed with the legacy format, iOS finds no rules. Check it with sudo swcutil verify on a Mac.

What is happening

AASA structure error: an apple-app-site-association file that parses as JSON but does not follow the applinks > details > appIDs and components layout that Apple documents.

Apple's applinks object has three keys: defaults, details and substitutionVariables. Only details is needed for basic universal links. Each details entry pairs the apps with the URL patterns they handle.

  • A top-level array ([...]) instead of an object is the most obvious version of this error.
  • appId or AppIDs instead of appIDs silently fails, because keys are case-sensitive.
  • components placed outside a details entry is ignored.

Why does this happen?

Most structure errors come from copying an old tutorial or mixing the two formats Apple has used. The legacy format used appID (a string) and paths; the current one uses appIDs (an array) and components.

  • Apple says: "Please avoid mixing formats. Doing so may result in unexpected behavior."
  • Older guides and forum threads describe an empty "apps": [] key inside applinks for the iOS 9 to 12 format. Current Apple documentation does not mention it, so treat it as legacy.
  • webcredentials and appclips use an apps array, not details. Apple notes that "the details dictionary only applies to the applinks service type".

How to confirm it

  1. Fetch the file: curl -s https://example.com/.well-known/apple-app-site-association.
  2. Check the first character is { and the top-level keys include applinks.
  3. Compare it with the example in the universal links setup guide: a top-level object, a non-empty details array, and entries with both appIDs and components. Then run sudo swcutil verify against a real URL.
  4. On a Mac, test a URL with sudo swcutil verify -d example.com -j apple-app-site-association -u https://example.com/buy/1. A good file prints Pattern "..." matched.

How to fix it

  1. Make the top level an object.
  2. Add applinks with a details array.
  3. In each entry, use appIDs (array of strings) and components (array of objects).
  4. Remove any appID and paths keys from entries that use components, so formats are not mixed.
  5. Keep webcredentials and appclips as separate top-level keys with apps arrays.
  6. Deploy and reinstall the app on a test device.

The structure from Apple's own example:

{
  "applinks": {
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.app"],
        "components": [
          { "#": "no_universal_links", "exclude": true },
          { "/": "/buy/*" },
          { "/": "/help/*", "?": { "articleNumber": "????" } }
        ]
      }
    ]
  },
  "webcredentials": { "apps": ["ABCDE12345.com.example.app"] }
}

If the file has no applinks key at all, see no applinks section. The universal links setup guide walks through the structure.

FAQ

Common questions

Do I still need the "apps" empty array inside applinks?

Current Apple documentation does not mention it. It appears in older guides and forum threads for the iOS 9 to 12 format, so it is not needed for the `appIDs` and `components` format.

Can I keep the old paths format?

Apple still documents the legacy `appID` and `paths` format in its debugging technote. What Apple warns against is mixing the two in one file, so pick one and use it throughout.

Are AASA keys case-sensitive?

Yes. JSON keys are matched exactly, so `appIds` or `Details` are different keys from `appIDs` and `details`, and iOS ignores them.

What are defaults and substitutionVariables for?

`defaults` sets global matching settings, such as case sensitivity, for every rule on the domain. `substitutionVariables` defines named lists of strings that patterns can reuse, and Apple provides built-in ones such as `lang` and `region`.

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.

Which UTM parameters are required?

Use utm_source, utm_medium and utm_campaign on every campaign link. utm_term and utm_content are optional and help you compare keywords or ad variants.