Vouch
Link Doctor

Why don’t my links open the app?

Link Doctor reads your domain from the outside, exactly as Apple and Google read it, and reports what is wrong with the fix for each thing. It needs no account and no SDK, and it works on any domain, whoever hosts it.

The host your links are served from. Everything else is optional, but the checks that need an app identity are skipped without it.

iOS

The ten-character prefix Apple assigns your developer account.

Android

Take it from Play Console under App signing, not from your upload key. Any formatting is accepted.

One per line. Each is matched against the path patterns the two files declare.

No account, no sign-up. Only the domain you enter is fetched.
What it checks

The six things that break links

The file is reachable, over HTTPS, with no redirect
Both platforms fetch the association file directly and refuse to follow a redirect. A host that redirects the apex to www, or http to https, serves nothing as far as they are concerned.
The content type and the bytes
application/json, valid JSON, and no byte-order mark. A BOM in front of the opening brace is invisible in an editor and fatal to the parser.
The app IDs match, prefix included
An iOS app ID is the Team ID and the bundle identifier together. A file that lists the bundle identifier alone verifies for nobody.
The fingerprint is the one Google signs with
If Play App Signing is on, Google re-signs your release with its own key. A file listing only the upload key's fingerprint works in testing and fails for every real user.
The paths you actually link to are covered
Path patterns are declared separately per platform, and they drift. This is why a link opens the app on Android and the browser on iOS.
Apple's mirror, which is the copy devices read
iOS does not fetch from your server; it fetches from Apple's CDN. A fixed file that Apple has not re-fetched is still broken on the phone.
In your CI

The same check runs in your build

vouch-doctor is a single Go binary that performs these checks locally. Point it at a build and it reads the team ID, bundle identifier, package name and signing fingerprint out of the binary rather than trusting flags, which is how it catches an upload key published as the release fingerprint.

Terminal
go install github.com/vouch-dev/vouch/services/vouchd/cmd/vouch-doctor@latest vouch-doctor check --host links.example.com \  --bundle-id app.roam.ios --team-id ABCDE12345 \  --package app.roam --aab build/app-release.aab

It exits 0 when nothing is wrong, 1 when there is an error-severity finding and 2 when the tool itself could not run, so a release that would break links fails the build. --json prints the whole report, and --warnings-as-errors tightens it.