Deep links for Shopify, Wix and every other locked-down host.
Your platform won't let you upload apple-app-site-association or assetlinks.json to /.well-known/. We host them on a subdomain you control and send everything else back to your main site.
Check your existing setup
Paste the domain users actually click. We'll fetch both files and tell you what's broken.
How it works
- Register your domain with VCurl.
- Give us your Apple Team ID, Android package names and SHA-256 fingerprints.
- Add your URL path rules. We generate and validate the file formats.
- Point a CNAME from your subdomain to us. We handle SSL.
What we serve
Each file is hosted at the path the OS expects, with the right Content-Type:
https://links.yourdomain.com/.well-known/apple-app-site-association
https://links.yourdomain.com/.well-known/assetlinks.json
We also serve the legacy AASA location for older iOS clients (pre-iOS 9.3). Same file, no extra setup:
https://links.yourdomain.com/apple-app-site-association
What you provide
- Apple Team ID and bundle identifiers
- Android package names and SHA-256 cert fingerprints
- URL path patterns (e.g.
/u/*,/invite/*) - A CNAME record pointing to
customers.siteassociation.com
What you don't deal with
- SSL certificates. We issue and renew them.
- JSON format mistakes. We validate before publish.
- Server uptime. Everything sits behind a CDN.
- A bill. It's free.
Shareable links
If the deep link doesn't resolve to an app (no app installed, link opened on desktop, path not registered), we redirect to your main domain and keep the path and query string intact.
https://app.example.com/product/test
↓ no app? fall back to web
https://example.com/product/test
Same URL works in iMessage, in an email, on a laptop, or on a phone without the app. You set the fallback domain in the dashboard.
Redirect analytics
Every redirect is logged with timestamp, path, referrer, user-agent class (iOS, Android, desktop), country, and whether the app opened or the user fell through to web. View it in your VCurl dashboard, export to CSV, or pull it via API. No third-party trackers and no cookies on the redirect, just server-side logs.
Why this exists
Apple Universal Links and Android App Links need specific JSON files at fixed paths on the domain users tap. Apple looks for /.well-known/apple-app-site-association, Android looks for /.well-known/assetlinks.json.
Most hosted site platforms don't let you put files there. Shopify, Wix, Squarespace, Webflow, BigCommerce, Carrd, Framer, Notion, Ghost. None of them give you write access to /.well-known/ on your storefront domain, and most won't let you control response headers or MIME types either. Even when you can upload a file, redirects or HTML challenge pages break Apple's strict validation.
The fix is to put your deep links on a subdomain you control. Something like app.yourstore.com points at us. We serve the association files the way Apple and Google want them, and anything that isn't a deep link goes back to your real site at yourstore.com. Customers see one branded URL that opens the app when it can and your website otherwise.
Who this is for
- Shopify merchants with a native mobile app that needs Universal Links from product and collection pages.
- Wix, Squarespace, Webflow, Framer, Carrd sites where the platform owns the root domain.
- BigCommerce, WooCommerce on managed hosts without root file access.
- Substack, Ghost, Notion-as-a-site, Beehiiv publications with companion mobile apps.
- Anyone whose marketing site lives somewhere they don't fully control.
Migrating from Branch or Firebase Dynamic Links?
Branch.io has been winding down its free tier and Firebase Dynamic Links was deprecated by Google and fully shut down in 2025. If you've been using either, your old deep link domain (something like yourapp.app.link or yourapp.page.link) either already stopped working or will soon.
The good news: the hard parts (AASA, assetlinks, signing keys) are exactly the same. You're really just moving from a vendor-owned domain to one you own.
What changes: deep link URLs go from yourapp.page.link/x to links.yourdomain.com/x. You own the domain, you keep the analytics, you don't pay per click.
What stays the same: Team ID, bundle IDs, package names, fingerprints. Hand them to us and we'll generate the equivalent association files.
Old links in the wild will keep working as long as your provider hasn't fully cut service. After they do, traffic to the old domain stops resolving entirely, so cut over as soon as you can update your apps.
Setup, end to end
1. Register your domain in VCurl
Sign in at vcurl.co and add the domain you want links to live under, for example app.example.com. This is the same domain you'd use for shortened URLs.
Also set the fallback domain: where traffic should land when the app isn't installed (e.g. example.com). We preserve the path on redirect.
2. Add a CNAME record
At your DNS provider, point the subdomain to us:
links.yourdomain.com. CNAME customers.siteassociation.com.
We detect the record, provision a TLS certificate via Let's Encrypt, and start serving over HTTPS within a few minutes. Don't proxy through Cloudflare's orange-cloud option. Apple and Google fetch these files directly, and any redirect or HTML challenge page will break validation.
3. Provide your app identifiers
We need your Apple Team ID and the bundle ID of each app that should handle links:
Team ID: ABCD1234EF
Bundle IDs: com.yourcompany.app
com.yourcompany.app.beta
Find the Team ID in your Apple Developer account under Membership details. Bundle IDs come from each app's Xcode project (PRODUCT_BUNDLE_IDENTIFIER) or from the App Store Connect listing.
We need each package name and the SHA-256 fingerprint of the signing certificate. Where you get the fingerprint depends on how your app is signed:
If you use Google Play App Signing (the managed option where Play holds your release key): grab the fingerprint from the Play Console under Setup → App integrity → App signing. Use the App signing key certificate SHA-256, not the upload key. Android verifies against the key Play actually signs your releases with.
If you manage your own keystore: run keytool against your release keystore:
keytool -list -v -keystore your-release-key.keystore \
-alias your-alias | grep SHA256
Either way, give us:
Package: com.yourcompany.app
Fingerprint: AA:BB:CC:DD:EE:FF:... (release / Play signing)
11:22:33:44:55:66:... (debug, optional)
4. Define your URL rules
Tell us which paths on your domain should open the app. We accept glob patterns and generate the right format for each platform:
/u/* → open in app
/invite/* → open in app
/account/* → web only (exclude)
/* → fallback to browser
We translate this into iOS components entries (with ?, # and NOT handling) and Android relation and target blocks automatically.
5. We validate, then publish
Before we serve anything we check:
- JSON parses and matches the official schema
- No trailing
.jsonon the Apple file (a common gotcha) - Bundle IDs and Team IDs are correctly concatenated as
TEAMID.bundle.id - SHA-256 fingerprints are uppercase, colon-separated, 32 bytes
- Files are served as
application/jsonwith no redirects
Once it passes you'll see green checkmarks in the dashboard and your files are live at:
https://links.yourdomain.com/.well-known/apple-app-site-association
https://links.yourdomain.com/.well-known/assetlinks.json
6. Verify on device
On iOS, install your app and tap a link from Notes or Messages. It should open the app directly. On Android, run adb shell pm verify-app-links --re-verify com.yourcompany.app then check status with adb shell pm get-app-links com.yourcompany.app. You want verified for each declared host.
FAQ & gotchas
Is it really free? What's the catch?
All VCurl services are free. We don't sell upsells, paid tiers, or "pro" plans on this product. VCurl exists as a developer toolkit alongside our enhost hosting infrastructure, where the actual business sits. Site Association costs us cents per domain to serve and giving it away brings developers into the wider VCurl ecosystem.
What happens if VCurl goes down?
Your deep links stop opening apps until we're back up, and any fallback redirects to your main domain pause. iOS will keep its cached copy of AASA for a while so existing installs may still work briefly. You can check live status at uptime.enst.uk.
We run on a CDN with multiple regions so outages are rare, but you should rule us out first if your links stop working.
Can I export my config?
Yes. The dashboard has a one-click export of your current AASA and assetlinks.json files plus the underlying config (Team ID, bundle IDs, packages, fingerprints, URL rules) as JSON. If you ever leave us, you can hand that to whoever you switch to. No lock-in.
Why a subdomain, not my root domain?
Because we can't (and shouldn't) take over your root domain. Your storefront, marketing site, blog and email all live there. A subdomain you CNAME to us is the only clean way to serve files at /.well-known/ without us controlling your whole site.
It also means deep link traffic is cleanly separable in your analytics, and if you ever cut us off, only the subdomain breaks.
Will this work with my existing analytics or attribution provider?
Yes. We pass the original path and query string through to your fallback domain, so anything that hangs off URL params (UTMs, click IDs, affiliate codes) is preserved. The redirect happens server-side and is invisible to most attribution tools.
Why does the AASA file have to not be redirected?
Apple validates AASA over a separate fetch from their CDN, and any HTTP redirect on the response (including http to https or apex-to-www) makes them reject the file. We serve directly on the subdomain you registered, no redirects, so this never trips you up.
What's "all-or-nothing" Android verification?
If any path you declare in your Android manifest fails to verify against assetlinks.json, the whole host is marked unverified and none of your links auto-open. We validate the file against your declared package names and fingerprints before we publish, so you can't accidentally ship a setup that breaks every link.
What if I change my signing key or add a new app?
Update the config in your dashboard and the new files publish automatically. We keep old fingerprints alongside new ones for as long as you need, which is useful during key rotation or when supporting multiple build variants.
Do you serve App Clips, Smart App Banners or web credentials?
Yes. AASA can declare applinks, appclips, webcredentials and activitycontinuation in the same file. You configure each in the dashboard and we generate the right block. The setup checker on this page also detects which keys you currently have published.