{"id":1462,"date":"2026-06-15T13:00:00","date_gmt":"2026-06-15T18:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1462"},"modified":"2026-03-07T03:49:25","modified_gmt":"2026-03-07T08:49:25","slug":"app-indexing-verification","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/app-indexing-verification\/","title":{"rendered":"Verifying App Indexing: Tools and Techniques"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Setting up app indexing is only half the work. Verifying that it actually works is the other half. Verification failures are often silent: your app does not appear in search results, but there is no error message telling you why. The verification files might have a typo, the intent filters might not match, or the structured data might be malformed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers every tool and technique for verifying app indexing on both Android and iOS. For the setup process, see <a href=\"https:\/\/tolinku.com\/blog\/google-app-indexing-setup\/\">Google App Indexing<\/a>. For getting app content into search, see <a href=\"https:\/\/tolinku.com\/blog\/app-content-search-results\/\">app content in search results<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Android Verification<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Digital Asset Links Validator<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Google provides an API to verify your <code>assetlinks.json<\/code> file:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Verify your domain&#39;s Digital Asset Links\ncurl -s &quot;https:\/\/digitalassetlinks.googleapis.com\/v1\/statements:list?source.web.site=https:\/\/www.yourapp.com&amp;relation=delegate_permission\/common.handle_all_urls&quot; | python3 -m json.tool\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A successful response includes your app&#39;s package name and SHA-256 fingerprint:<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;statements&quot;: [\n    {\n      &quot;source&quot;: { &quot;web&quot;: { &quot;site&quot;: &quot;https:\/\/www.yourapp.com&quot; } },\n      &quot;relation&quot;: &quot;delegate_permission\/common.handle_all_urls&quot;,\n      &quot;target&quot;: {\n        &quot;androidApp&quot;: {\n          &quot;packageName&quot;: &quot;com.yourapp.android&quot;,\n          &quot;certificate&quot;: {\n            &quot;sha256Fingerprint&quot;: &quot;AA:BB:CC:...&quot;\n          }\n        }\n      }\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the response has an empty <code>statements<\/code> array, your <code>assetlinks.json<\/code> is not being found or parsed correctly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common assetlinks.json Issues<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Issue<\/th>\n<th>Symptom<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>File not found<\/td>\n<td>Empty statements array<\/td>\n<td>Check URL: <code>https:\/\/yourapp.com\/.well-known\/assetlinks.json<\/code><\/td>\n<\/tr>\n<tr>\n<td>Wrong Content-Type<\/td>\n<td>Validation fails<\/td>\n<td>Serve with <code>Content-Type: application\/json<\/code><\/td>\n<\/tr>\n<tr>\n<td>Wrong SHA-256<\/td>\n<td>Verification fails<\/td>\n<td>Use Play Console fingerprint (Setup &gt; App signing)<\/td>\n<\/tr>\n<tr>\n<td>Missing package name<\/td>\n<td>Partial verification<\/td>\n<td>Verify <code>package_name<\/code> matches your <code>applicationId<\/code><\/td>\n<\/tr>\n<tr>\n<td>HTTP instead of HTTPS<\/td>\n<td>Not fetched<\/td>\n<td>Must be served over HTTPS<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">adb Verification Commands<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On a connected Android device or emulator:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Check App Links verification status\nadb shell pm get-app-links com.yourapp.android\n\n# Force re-verification\nadb shell pm verify-app-links --re-verify com.yourapp.android\n\n# Check verification state for a specific domain\nadb shell pm get-app-links --user 0 com.yourapp.android\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output shows verification status per domain:<\/p>\n\n\n\n<pre><code>com.yourapp.android:\n    ID: your-app-id\n    Signatures: [AA:BB:CC:...]\n    Domains:\n        www.yourapp.com: verified\n        links.yourapp.com: verified\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If a domain shows <code>none<\/code> or <code>error<\/code> instead of <code>verified<\/code>, the <code>assetlinks.json<\/code> file is not correctly configured for that domain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing Deep Links via adb<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Verify that your app handles specific URLs:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Open a deep link\nadb shell am start -a android.intent.action.VIEW \\\n  -d &quot;https:\/\/www.yourapp.com\/products\/123&quot; \\\n  com.yourapp.android\n\n# Open a deep link without specifying the package (tests auto-verification)\nadb shell am start -a android.intent.action.VIEW \\\n  -d &quot;https:\/\/www.yourapp.com\/products\/123&quot;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the second command opens your app without showing a disambiguation dialog (the &quot;Open with&quot; chooser), App Links verification is working correctly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">iOS Verification<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">apple-app-site-association Validation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fetch and validate your AASA file:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Fetch the AASA file\ncurl -s https:\/\/www.yourapp.com\/.well-known\/apple-app-site-association | python3 -m json.tool\n\n# Check the response headers\ncurl -sI https:\/\/www.yourapp.com\/.well-known\/apple-app-site-association\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>HTTP 200<\/strong> status code (not a redirect).<\/li>\n<li><strong>Content-Type:<\/strong> <code>application\/json<\/code> (not <code>text\/html<\/code>).<\/li>\n<li><strong>File contains<\/strong> your Team ID and Bundle ID in the correct format.<\/li>\n<li><strong>No redirect:<\/strong> Apple does not follow redirects when fetching AASA files (as of iOS 14+, Apple uses a CDN).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">AASA File Format<\/h3>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;applinks&quot;: {\n    &quot;apps&quot;: [],\n    &quot;details&quot;: [\n      {\n        &quot;appIDs&quot;: [&quot;TEAMID.com.yourapp.ios&quot;],\n        &quot;components&quot;: [\n          { &quot;\/&quot;: &quot;\/products\/*&quot; },\n          { &quot;\/&quot;: &quot;\/articles\/*&quot; }\n        ]\n      }\n    ]\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Common issues:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Issue<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>Wrong Team ID<\/td>\n<td>Check in Apple Developer Portal &gt; Membership<\/td>\n<\/tr>\n<tr>\n<td>Wrong Bundle ID<\/td>\n<td>Check in Xcode &gt; Target &gt; General<\/td>\n<\/tr>\n<tr>\n<td>Missing path patterns<\/td>\n<td>Add <code>components<\/code> entries for each URL pattern<\/td>\n<\/tr>\n<tr>\n<td>File served as HTML<\/td>\n<td>Configure server to serve JSON Content-Type<\/td>\n<\/tr>\n<tr>\n<td>Redirect instead of direct serve<\/td>\n<td>Apple CDN does not follow redirects; serve directly<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Apple&#39;s CDN Check<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apple caches AASA files through their CDN. You can check what Apple has cached:<\/p>\n\n\n\n<pre><code class=\"language-bash\">curl -s &quot;https:\/\/app-site-association.cdn-apple.com\/a\/v1\/www.yourapp.com&quot; | python3 -m json.tool\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the cached version is outdated, you may need to wait up to 24 hours for the CDN to refresh. There is no way to force a cache invalidation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing Universal Links on Device<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On a physical iOS device:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open Notes or Messages.<\/li>\n<li>Paste a deep link URL (e.g., <code>https:\/\/www.yourapp.com\/products\/123<\/code>).<\/li>\n<li>Long-press the link. If Universal Links are working, the context menu shows &quot;Open in YourApp.&quot;<\/li>\n<li>Tap the link. If it opens the app directly (without going through Safari), Universal Links are verified.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If the link opens Safari instead, Universal Links verification has failed. Check:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The AASA file is correct.<\/li>\n<li>Your app has the Associated Domains entitlement (<code>applinks:www.yourapp.com<\/code>).<\/li>\n<li>The user has not previously chosen &quot;Open in Safari&quot; for your domain (this overrides Universal Links).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Google Search Console Verification<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Link Your App<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <a href=\"https:\/\/search.google.com\/search-console\" rel=\"nofollow noopener\" target=\"_blank\">Search Console<\/a> &gt; Settings &gt; Associations.<\/li>\n<li>Click &quot;Associate&quot; and select your Android app.<\/li>\n<li>Verify ownership through the Play Console.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">URL Inspection<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use the URL Inspection tool to check individual pages:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Enter a URL that should have app indexing.<\/li>\n<li>Look for &quot;Mobile usability&quot; and &quot;App&quot; sections.<\/li>\n<li>Verify that Google detects the <code>&lt;link rel=&quot;alternate&quot;&gt;<\/code> tag or structured data.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Enhancement Reports<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Check for app indexing-specific issues:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to Enhancements in the left sidebar.<\/li>\n<li>Look for &quot;SoftwareApplication&quot; or other structured data types.<\/li>\n<li>Review any errors or warnings.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Performance Filtering<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Filter the Performance report to see app-specific data:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to Performance &gt; Search Results.<\/li>\n<li>Click &quot;Search Appearance&quot; filter.<\/li>\n<li>Select &quot;App Install&quot; or review clicks\/impressions that include app results.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Automated Verification Script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a script that checks all verification endpoints:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">async function verifyAppIndexing(domain, packageName, teamId, bundleId) {\n  const results = { android: {}, ios: {}, web: {} };\n\n  \/\/ 1. Check assetlinks.json\n  const assetlinks = await fetch(`https:\/\/${domain}\/.well-known\/assetlinks.json`);\n  results.android.assetlinksStatus = assetlinks.status;\n  if (assetlinks.ok) {\n    const data = await assetlinks.json();\n    const hasPackage = JSON.stringify(data).includes(packageName);\n    results.android.packageFound = hasPackage;\n  }\n\n  \/\/ 2. Check AASA\n  const aasa = await fetch(`https:\/\/${domain}\/.well-known\/apple-app-site-association`);\n  results.ios.aasaStatus = aasa.status;\n  if (aasa.ok) {\n    const data = await aasa.json();\n    const hasTeamBundle = JSON.stringify(data).includes(`${teamId}.${bundleId}`);\n    results.ios.appIdFound = hasTeamBundle;\n  }\n\n  \/\/ 3. Check Google&#39;s DAL API\n  const dalUrl = `https:\/\/digitalassetlinks.googleapis.com\/v1\/statements:list?source.web.site=https:\/\/${domain}&amp;relation=delegate_permission\/common.handle_all_urls`;\n  const dal = await fetch(dalUrl);\n  const dalData = await dal.json();\n  results.android.dalVerified = dalData.statements?.length &gt; 0;\n\n  \/\/ 4. Check Apple CDN\n  const appleCdn = await fetch(`https:\/\/app-site-association.cdn-apple.com\/a\/v1\/${domain}`);\n  results.ios.appleCdnStatus = appleCdn.status;\n\n  return results;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run this script after any configuration change and before each app release.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verification Checklist<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After setup, verify each item:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><input disabled=\"\" type=\"checkbox\"> <code>assetlinks.json<\/code> returns 200 with correct Content-Type<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> <code>assetlinks.json<\/code> contains correct package name and SHA-256 fingerprint<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Google&#39;s DAL API returns your app in the statements<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> <code>adb shell pm get-app-links<\/code> shows &quot;verified&quot; for your domain<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Deep links open the app without disambiguation dialog (Android)<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> <code>apple-app-site-association<\/code> returns 200 with correct Content-Type<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> AASA contains correct Team ID and Bundle ID<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Apple CDN has your AASA file cached<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Universal Links open the app from Notes\/Messages (iOS)<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Search Console shows your app as associated<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> URL Inspection detects app link annotations<\/li>\n<li><input disabled=\"\" type=\"checkbox\"> Structured data passes the Rich Results Test<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku Verification<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/docs\/developer\/app-links\/\">Tolinku<\/a> automatically generates and hosts both <code>assetlinks.json<\/code> and <code>apple-app-site-association<\/code> files based on your Appspace configuration. After configuring your app settings (package name, SHA-256 fingerprint, Team ID, Bundle ID), verify using the tools above that Tolinku is serving the correct files for your custom domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the setup process, see <a href=\"https:\/\/tolinku.com\/blog\/google-app-indexing-setup\/\">Google App Indexing setup<\/a>. For the broader strategy, see <a href=\"https:\/\/tolinku.com\/blog\/app-indexing-seo-mobile-apps\/\">app indexing and SEO for mobile apps<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Verify that your app content is correctly indexed in Google and Apple search. Use Search Console, adb commands, Digital Asset Links validators, and testing tools.<\/p>\n","protected":false},"author":2,"featured_media":1461,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Verifying App Indexing: Tools and Techniques","rank_math_description":"Verify that your app content is correctly indexed in search. Use Search Console, adb commands, and Digital Asset Links validators.","rank_math_focus_keyword":"app indexing verification","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-app-indexing-verification.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-app-indexing-verification.png","footnotes":""},"categories":[16],"tags":[25,64,20,354,24,63,80,91],"class_list":["post-1462","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-marketing","tag-android","tag-app-indexing","tag-deep-linking","tag-google-search","tag-ios","tag-seo","tag-testing","tag-verification"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1462"}],"version-history":[{"count":4,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1462\/revisions"}],"predecessor-version":[{"id":2608,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1462\/revisions\/2608"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1461"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}