App Links & Universal Links Auditor avatar

App Links & Universal Links Auditor

Pricing

Pay per usage

Go to Apify Store
App Links & Universal Links Auditor

App Links & Universal Links Auditor

Audit a public domain's Apple App Site Association and Android assetlinks.json files in one API call. Validates Universal Links and App Links configuration, returns per-platform breakdown, readiness score, grade, and recommendations.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Sanskar Jaiswal

Sanskar Jaiswal

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Audits a public domain's Apple App Site Association file (Universal Links) and Android assetlinks.json file (App Links) in one API call. Fetches both well-known files, validates them against the Apple and Google requirements, and returns a per-platform breakdown, a readiness score from 0 to 100, a letter grade, issues, and recommendations as structured JSON.

Use cases

  • Mobile app teams verifying domain association files after releases, CMS migrations, and CDN cutovers
  • iOS developers validating AASA structure before submitting an app that uses Universal Links
  • Android developers validating assetlinks.json statements before enabling App Links verification
  • Agency consultants running recurring deep-link posture checks across client domains
  • QA pipelines gating deploys on broken or malformed association files
  • Web engineering teams confirming association files are served over HTTPS, without redirects, and without signing (no file extension on AASA)

Input

FieldTypeDefaultDescription
startUrlstring(required)Public domain or base URL to audit. A bare hostname gets the https scheme prepended. Private IP ranges, URL credentials, and non-HTTP schemes are rejected.
timeoutSecondsinteger10Request timeout per file, from 3 to 30 seconds.
maxBytesinteger131072Maximum response body size to download and parse per file, from 1 KB to 512 KB.

Output

One dataset item per run:

FieldTypeDescription
inputUrlstringURL as provided in the input.
finalUrlstringNormalized base URL after validation.
httpsbooleanWhether the base URL uses HTTPS.
okbooleanWhether all HTTP requests completed without network errors.
checkedAtstringISO 8601 timestamp of the check.
aasaCheckedbooleanWhether the Apple check ran (always true).
aasaFoundbooleanWhether the AASA file was found (200 on the well-known path or the legacy root path).
aasaUrlstringThe AASA URL that produced the result.
aasaStatusinteger or nullHTTP status of the AASA response.
aasaHttpsboolean or nullWhether the AASA file was served over HTTPS.
aasaContentTypestring or nullContent-Type of the AASA response.
aasaJsonValidboolean or nullWhether the AASA body parsed as JSON.
aasaParseErrorstring or nullJSON parse error for the AASA body, if any.
aasaAppCountintegerNumber of entries in the legacy top-level apps array (modern format should use none).
aasaDetailCountintegerNumber of entries in applinks.details.
aasaApplinksPresentbooleanWhether the applinks block is present.
aasaValidAppIdsintegerNumber of validly formatted app IDs in the legacy top-level apps array.
aasaInvalidAppIdsarrayInvalidly formatted app IDs in the legacy top-level apps array.
aasaWebcredentialsCountintegerNumber of apps in the webcredentials block.
aasaAppclipsPresentbooleanWhether a valid appclips block is present.
aasaDetailsarrayPer-detail analysis: appIDs, invalid appIDs, components, component issues, legacy paths, and per-entry issues.
aasaRedirectedbooleanWhether the AASA file was served through a redirect.
aasaRedirectIssuebooleanWhether the redirect is flagged as an issue (iOS may fail association behind redirects).
aasaIssuesarrayAll AASA issues found.
assetlinksCheckedbooleanWhether the Android check ran (always true).
assetlinksFoundbooleanWhether assetlinks.json was found (200).
assetlinksUrlstringThe assetlinks.json URL.
assetlinksStatusinteger or nullHTTP status of the assetlinks.json response.
assetlinksHttpsboolean or nullWhether assetlinks.json was served over HTTPS.
assetlinksContentTypestring or nullContent-Type of the assetlinks.json response.
assetlinksJsonValidboolean or nullWhether the assetlinks.json body parsed as JSON.
assetlinksParseErrorstring or nullJSON parse error for the assetlinks.json body, if any.
assetlinksTargetCountintegerNumber of statements in assetlinks.json.
assetlinksPackageCountintegerNumber of unique valid Android package names across statements.
assetlinksPackagesarrayThe unique valid Android package names.
assetlinksValidFingerprintsintegerNumber of validly formatted SHA-256 certificate fingerprints.
assetlinksInvalidFingerprintsarrayInvalidly formatted fingerprints.
assetlinksValidRelationsintegerNumber of valid delegate_permission relations.
assetlinksInvalidRelationsarrayInvalidly formatted relations.
assetlinksStatementsarrayPer-statement analysis: namespace, package, fingerprints, relations, and per-statement issues.
assetlinksIssuesarrayAll assetlinks.json issues found.
scoreintegerReadiness score from 0 to 100.
gradestringLetter grade from A+ to F.
issuesarrayCombined issues from both platforms.
recommendationsarrayActionable fixes for each platform.
errorstring or nullError message when the audit could not complete.

Example input

{
"startUrl": "https://www.wikipedia.org",
"timeoutSeconds": 10,
"maxBytes": 131072
}

Example output

{
"inputUrl": "https://www.wikipedia.org",
"finalUrl": "https://www.wikipedia.org/",
"https": true,
"ok": true,
"checkedAt": "2026-09-28T09:15:00.000Z",
"aasaChecked": true,
"aasaFound": true,
"aasaUrl": "https://www.wikipedia.org/.well-known/apple-app-site-association",
"aasaStatus": 200,
"aasaHttps": true,
"aasaContentType": "application/json",
"aasaJsonValid": true,
"aasaParseError": null,
"aasaAppCount": 0,
"aasaDetailCount": 1,
"aasaApplinksPresent": true,
"aasaValidAppIds": 0,
"aasaInvalidAppIds": [],
"aasaWebcredentialsCount": 0,
"aasaAppclipsPresent": false,
"aasaDetails": [
{
"index": 0,
"appIDs": ["TEAMID123.org.wikipedia.wiki"],
"appIDCount": 1,
"invalidAppIDs": [],
"components": [{ "index": 0, "path": "/*", "issues": [] }],
"componentCount": 1,
"componentIssues": 0,
"paths": [],
"issues": []
}
],
"aasaRedirected": false,
"aasaRedirectIssue": false,
"aasaIssues": [],
"assetlinksChecked": true,
"assetlinksFound": true,
"assetlinksUrl": "https://www.wikipedia.org/.well-known/assetlinks.json",
"assetlinksStatus": 200,
"assetlinksHttps": true,
"assetlinksContentType": "application/json",
"assetlinksJsonValid": true,
"assetlinksParseError": null,
"assetlinksTargetCount": 1,
"assetlinksPackageCount": 1,
"assetlinksPackages": ["org.wikipedia.wiki"],
"assetlinksValidFingerprints": 1,
"assetlinksInvalidFingerprints": [],
"assetlinksValidRelations": 1,
"assetlinksInvalidRelations": [],
"assetlinksStatements": [
{
"index": 0,
"namespace": "android_app",
"package_name": "org.wikipedia.wiki",
"sha256Fingerprints": ["AA:BB:...:99"],
"fingerprintCount": 1,
"relations": ["delegate_permission/common.handle_all_urls"],
"issues": []
}
],
"assetlinksIssues": [],
"score": 97,
"grade": "A+",
"issues": [],
"recommendations": [
"Both association files are well-formed. Schedule this audit periodically to catch deploy and CDN regressions."
],
"error": null
}

Security

  • Fetches only the three association paths on the audited domain: /.well-known/apple-app-site-association, /apple-app-site-association (legacy fallback), and /.well-known/assetlinks.json
  • HTTP and HTTPS only; rejects URL credentials, non-HTTP schemes, private IPv4 and IPv6 literals, and hostnames whose DNS resolves to private IP ranges
  • Redirects are revalidated against the SSRF rules before following; at most 3 redirects per file
  • Response bodies are capped by the maxBytes input (default 128 KB, hard max 512 KB)
  • Does not fetch appIDs, package names, or any URLs referenced inside the association files
  • No login, no JavaScript execution, no cookies, no stored page content

Pricing

EventPriceDescription
Actor start$0.005Charged once per run.
Domain audited$0.01Charged per domain audited (both platforms in one run).

A typical single-domain audit costs $0.015 per run.

FAQ

Does the actor check both Apple and Android files in one run? Yes. Every run fetches the AASA file (well-known path with legacy root fallback) and assetlinks.json, and returns per-platform results plus a combined score.

Does the actor validate the AASA JSON structure? Yes. It checks the applinks block, apps and details arrays, appID format (TEAMID.bundle.identifier), component shape (the "/" key, exclude, and allowed keys), legacy paths arrays, and the optional webcredentials and appclips blocks.

Does the actor validate assetlinks.json statements? Yes. It checks that the file is a JSON array of statements, each with a relation list, a target with namespace android_app, a valid Android package name, and SHA-256 certificate fingerprints in hex or base64 format.

What about redirects? iOS does not reliably follow redirects for the AASA file. The actor follows up to 3 redirects to complete the audit but flags the redirect as an issue when the AASA file is served behind one.

Can I audit multiple domains? Run the actor once per domain, or schedule it across your domain list for recurring monitoring.

Does the actor open the app or test deep links end to end? No. It audits the server-side association files, which are the most common point of failure. End-to-end deep-link testing requires a device.