Glossary/Android platform
Digital Asset Links
Definition
Digital Asset Links is an open protocol for publishing verifiable statements in which one digital asset, such as a website, grants a specific permission to another, such as a mobile app identified by its package name and signing certificate fingerprint.
It is routinely confused with the file that implements it. `assetlinks.json` is one serialisation of one statement type; the protocol is broader, and it is what Android App Links verification, Chrome credential sharing, Trusted Web Activities and Instant Apps all sit on top of. Understanding the protocol is what lets you debug the cases where the file looks correct and the permission still is not granted.
The statement, as the protocol defines it
A statement has exactly three parts: the source asset making the claim, the relation being granted, and the target asset receiving it. Everything else is transport.
{
"source": {
"web": { "site": "https://shop.example.com" }
},
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"androidApp": {
"package_name": "com.example.shop",
"certificate": {
"sha256_fingerprint":
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
}
}
}
}The file at /.well-known/assetlinks.json is an array of these objects with the source omitted, because the source is implied by where the file is hosted. That omission is the whole reason the protocol and the file get conflated — the file only ever expresses statements *from* the domain serving it.
| Element | Values | Notes |
|---|---|---|
| Source / target asset | web.site, androidApp | A web asset is scheme, host and optional port — no path |
delegate_permission/common.handle_all_urls | Relation | Grants App Links URL handling — the one almost everyone needs |
delegate_permission/common.get_login_creds | Relation | Shares saved credentials between site and app |
delegate_permission/common.use_as_origin | Relation | Used by Trusted Web Activities |
A web asset has no path, and no wildcards
https://example.com and https://www.example.com are different assets, as are http and https and different ports. There is no wildcard host syntax. A statement list must be published on every hostname you want verified, which is why www and apex both need the file even when one redirects to the other — and a redirect does not satisfy verification.
Statement lists and the include mechanism
A statement list can delegate to another location rather than enumerating statements inline, which is how large organisations centralise the file across many hostnames.
[{
"include": "https://central.example.com/.well-known/statements.json"
}]- The include target must be served over HTTPS with a valid certificate.
- Statements in the included list still apply to the *including* host, not to the host serving them.
- Nesting depth is limited, and a broken include invalidates the whole list rather than degrading to the inline statements.
- It does not remove the need for the file on each hostname — it only removes the need to maintain the statement content in each place.
Includes trade one failure mode for another
You stop having to redeploy twelve hosts to rotate a fingerprint, and you start having a single URL whose outage breaks App Links verification on all twelve. If you use includes, monitor the include target as a production dependency.
Verifying a statement without a device
Google runs a public API that evaluates the protocol the same way Android does, which is the fastest way to distinguish "my file is wrong" from "my file is right and the device has not re-verified".
curl -s 'https://digitalassetlinks.googleapis.com/v1/statements:list?\
source.web.site=https://shop.example.com&\
relation=delegate_permission/common.handle_all_urls' | jq
# A useful response contains "statements" and an empty "debugString".
# Errors you will actually see:
# "Unable to fetch" ....... 404, auth wall, or a redirect
# "Content-Type" .......... served as text/html instead of application/json
# "malformed" ............. trailing comma, BOM, or a fingerprint with spaces
# And the device-side truth, which the API cannot tell you:
adb shell pm get-app-links com.example.shop| Statement List API says | Device says | Diagnosis |
|---|---|---|
| Statements returned | verified | Working |
| Statements returned | none or legacy_failure | File is fine; verification has not re-run. Reinstall or re-verify |
| Statements returned | Fingerprint mismatch | Wrong signing key — likely upload key vs Play App Signing |
Unable to fetch | none | Hosting problem: redirect, 404 or auth wall |
Wrong package_name | none | Statement targets a different app |
| Empty statements | none | File served, but the relation does not match |
The overwhelmingly common cause of a valid-looking file that does not verify is the SHA-256 fingerprint: Play App Signing re-signs your app with a key you never handled, so the fingerprint from your local keystore is the wrong one to publish.
AASA and assetlinks generator
Our generator produces a statement list with the correct relation and fingerprint formatting for every hostname you need it on, alongside the iOS equivalent, so the two platforms' association files stay in step.
Open the aasa and assetlinks generator →Frequently asked questions
- What is Digital Asset Links?
- It is an open protocol for publishing verifiable statements in which one digital asset grants a specific permission to another — most commonly a website declaring that a particular Android app, identified by package name and signing certificate fingerprint, may handle its URLs. Android App Links verification, Chrome credential sharing and Trusted Web Activities are all built on it.
- What is the difference between Digital Asset Links and assetlinks.json?
- Digital Asset Links is the protocol, defining what a statement is and which relations exist; assetlinks.json is the file format that publishes those statements for a single hostname. The file omits the statement's source because it is implied by the domain serving it, which is why the two are so often conflated.
- What relation types does Digital Asset Links support?
- The one most developers need is delegate_permission/common.handle_all_urls, which grants an app the right to handle a site's URLs and underpins Android App Links. The protocol also defines delegate_permission/common.get_login_creds for sharing saved credentials between a site and an app, and delegate_permission/common.use_as_origin, used by Trusted Web Activities.
- Can a Digital Asset Links statement use a wildcard domain?
- No. A web asset is a scheme, host and optional port with no path and no wildcard syntax, so example.com and www.example.com are distinct assets requiring separate statement lists. A redirect between them does not satisfy verification either, which is why both hostnames need the file published directly.
- How do I check a Digital Asset Links statement is valid?
- Query Google's Statement List API at digitalassetlinks.googleapis.com with your site and the relation you expect, which evaluates the protocol exactly as Android does and returns a debug string naming the failure. Then check the device separately with adb shell pm get-app-links, since a valid statement and an unverified device are different problems with different fixes.
Related terms
- assetlinks.json — assetlinks.json is a Digital Asset Links statement file hosted at a domain's /.well-known/ path that authorises a named Android app, identified by package name and signing certificate fingerprint, to handle that domain's URLs.
- Android App Link — An Android App Link is an HTTPS URL that opens an Android app directly, without a chooser dialog, because the system has verified through a file on the domain that the app is authorised to handle it.
- Android App Link Verification — Android App Link verification is the process by which Android confirms, at install time, that a domain named in an app's intent filter publishes an assetlinks.json file authorising that app to handle its URLs.
- SHA-256 Certificate Fingerprint — A SHA-256 certificate fingerprint is the SHA-256 hash of an app signing certificate, written as 32 colon-separated hexadecimal bytes, used to prove that a specific build was signed by a specific key.
- Validating assetlinks.json — Validating assetlinks.json means confirming four separate things: that Android can fetch the file, that it parses as a valid statement list, that it names the fingerprint of the shipped build, and that verification passed on a device.