Vouch
Links

Domains and association files

Hosted subdomains, custom domains, and the hourly check that tells you a link is broken before your users do.

A link needs a domain, and the operating systems will only open your app from that domain if a file at a well-known path says they may. Vouch hosts the domain, generates the file and keeps checking it.

Adding a domain

A hosted subdomain works immediately, with no DNS to configure:

curl -X POST https://api.vouch.dev/v1/apps/app_123/domains \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"host":"roam.vouch.dev"}'

A custom domain needs you to prove you own it. The response carries a CNAME target and a verification token; publish either, then verify:

curl -X POST https://api.vouch.dev/v1/domains/dom_123/verify \
  -H "Authorization: Bearer sk_live_…"
ProofRecord
CNAMEPoint the host at the cname_target in the response.
TXTPublish the verification_token at _vouch.yourdomain.com.

If verification fails, the error says what DNS actually returned rather than just refusing.

The association files

Vouch generates and serves both files for every verified domain, from your registered identifiers:

FilePlatformBuilt from
/.well-known/apple-app-site-associationiOSYour Apple Team ID and bundle identifier
/.well-known/assetlinks.jsonAndroidYour package name and every SHA-256 signing fingerprint

Register the Play App Signing fingerprint, not just your upload key. Google re-signs production builds with its own key, so a file listing only your upload fingerprint verifies in testing and fails for real users. The dashboard warns until it is added.

Path rules

By default every path on the domain opens the app. Path rules narrow that, and they go into the generated iOS file as well as being applied by the resolver.

curl -X PUT https://api.vouch.dev/v1/apps/app_123/path-rules \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"rules":[
        {"platform":"both","pattern":"/posts/*","kind":"allow"},
        {"platform":"both","pattern":"/admin/*","kind":"exclude"}
      ]}'

Rules are ordered and the first match decides. Check them against real URLs before you save:

curl -X POST https://api.vouch.dev/v1/apps/app_123/path-rules/preview \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"platform":"ios","urls":["https://roam.vouch.dev/posts/9","https://roam.vouch.dev/admin/x"]}'

The hourly check

Every verified domain is fetched at least hourly, the way Apple's CDN and Android's verifier fetch it: no redirects followed, content type checked, body compared against what we generated. Vouch also asks Apple's CDN what copy it is holding, because that is the copy that actually decides whether your links work on iOS.

A failure opens an alert and clears it when the next check passes.

curl https://api.vouch.dev/v1/domains/dom_123/checks \
  -H "Authorization: Bearer sk_live_…"

What each problem means

CodeMeaningUsual fix
redirectThe file redirects. Apple does not follow redirects.Serve it directly at the well-known path.
wrong_content_typeNot served as JSON.Send application/json.
invalid_jsonThe body is not valid JSON.Usually a proxy or error page is being served instead.
content_mismatchThe file differs from what Vouch generated.Something else is serving it; remove the override.
tls_errorThe certificate did not validate for this hostname.Issue a certificate covering the exact host.
timeoutThe host did not answer in time.Check the origin.
not_foundThe path returns 404.The domain is not routed to Vouch.
unexpected_statusSome other HTTP status.Read the status in the check.
too_largeThe file is over the size limit.Trim the path rules.
dns_errorThe hostname does not resolve.Check the DNS record.
unreachableThe host refused the connection.Check routing and firewalls.
read_errorThe connection dropped mid-body.Usually an origin problem.
apple_cdn_not_foundApple's CDN has no copy yet.Expected on a new domain; see below.
apple_cdn_staleApple's copy differs from yours.See below.
apple_cdn_unreachableApple's CDN could not be reached.Transient; the next check will retry.
apple_cdn_errorApple's CDN returned an error.Transient.

Each problem in the response carries a fix field with the specific remedy for your domain.

Apple's CDN

iOS does not usually fetch your file directly. It fetches Apple's cached copy, and Apple offers no API to force a refresh. That means a corrected file can take time to reach devices.

curl https://api.vouch.dev/v1/domains/dom_123/apple-cdn-guide \
  -H "Authorization: Bearer sk_live_…"

The guide returns the current steps for your domain, including the developer-mode entitlement that makes a device fetch your file directly while you are testing.

On this page