Watchlist deep links
A watchlist deep link is a URL that carries a list of Wi-Fi networks. Opening it adds those networks to the Wi-Fi watchlist, which makes it easy to share a curated list with someone else.
This page documents the URL format precisely so that anyone can generate their own links. The link is a verified Android App Link for the networksurvey.app domain.
What happens when the link is opened
Section titled “What happens when the link is opened”- On Android with Network Survey installed, the app opens its Watchlist page (the same page as More > Tools > Watchlist) and shows a confirmation prompt to add the networks.
- Otherwise (the app is not installed, or the link is opened in a desktop browser), the link loads a page on
networksurvey.appthat previews the networks in the list and offers a button to open the app, along with links to download it.
URL format
Section titled “URL format”https://networksurvey.app/app/watchlist?d=<base64url-json>| Part | Value |
|---|---|
| Scheme | https |
| Host | networksurvey.app |
| Path | /app/watchlist |
| Query parameter | d (the encoded payload) |
The single d parameter holds the entire payload. No other parameters are read.
Encoding the d parameter
Section titled “Encoding the d parameter”The value of d is a JSON document that has been encoded as follows:
- Serialize the payload to JSON and encode it as UTF-8 bytes.
- Encode those bytes with base64url (the URL-safe alphabet from RFC 4648, which uses
-and_in place of+and/). - Produce the value with no padding (omit any trailing
=) and no line wrapping.
Additional requirements:
- Use the URL-safe alphabet. The app decodes
das base64url only, so a value that contains standard base64’s+or/cannot be read and the link will not import. (The web preview page is more lenient, so a link that previews on the web can still fail in the app.) - Do not compress the JSON. The payload is plain UTF-8 JSON.
- Because base64url uses only URL-safe characters, the value needs no additional percent-encoding when placed in the query string.
- The encoded
dvalue must be at most 16 KB (16384 characters).
Payload schema
Section titled “Payload schema”The JSON payload is an object:
{ "v": 1, "name": "Acme networks", "entries": [ { "label": "HQ", "ssid": "HQ-Guest" }, { "label": "Lobby", "bssid": "a4:11:22:33:44:1c" } ]}| Field | Type | Required | Notes |
|---|---|---|---|
v | integer | Yes | Schema version. Must be exactly 1. |
name | string | No | A name for the list, shown in the import prompt. Maximum 100 characters. When absent or blank, a generic prompt title is used. |
entries | array | Yes | The networks to add. Must contain 1 to 100 entries. |
entries[].label | string | No | A display name for the entry. When absent, the app falls back to the SSID, then the BSSID. Maximum 100 characters. |
entries[].ssid | string | No* | The Wi-Fi network name. Maximum 32 characters. Case is preserved but matched case-insensitively. |
entries[].bssid | string | No* | An access point MAC address in the form XX:XX:XX:XX:XX:XX. Case-insensitive; stored in lower case. |
* Each entry must include at least one of ssid or bssid.
Matching rules for an entry
Section titled “Matching rules for an entry”- An entry with only an
ssidmatches any access point broadcasting that network name. - An entry with only a
bssidmatches that specific access point. - An entry with both
ssidandbssidmatches only when both are seen together (logical AND). To match on just one field, include only that field.
An entry with neither ssid nor bssid has nothing to match and is skipped.
Validation and limits
Section titled “Validation and limits”Every value is validated before anything is imported. Validation is all or nothing: if any value is out of bounds (for example a malformed BSSID or an over-long SSID), the entire link is rejected rather than partially imported or truncated. The one exception is an entry with no identifier at all (neither ssid nor bssid), which is simply skipped; if that leaves no valid entries, the link is rejected.
| Rule | Limit |
|---|---|
v | Must equal 1 |
| Number of entries | 1 to 100 |
ssid length | Up to 32 characters |
label length | Up to 100 characters |
name length | Up to 100 characters |
bssid format | Must match ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ |
Encoded d length | Up to 16 KB |
Control characters and Unicode format characters (for example zero-width spaces) are stripped from the name, label, and ssid text.
Import behavior
Section titled “Import behavior”When a valid link is opened:
- The app always shows a confirmation prompt before saving anything.
- The import merges into the existing watchlist. Only networks that are not already present are added; duplicates (matched case-insensitively on SSID and BSSID, including repeats within the link) are skipped, and existing entries are never modified.
- Confirming the import enables the watchlist feature.
Worked example
Section titled “Worked example”The following payload:
{"v":1,"name":"Acme networks","entries":[{"label":"HQ","ssid":"HQ-Guest"},{"label":"Lobby","bssid":"a4:11:22:33:44:1c"}]}encodes to this URL (whitespace in the JSON is insignificant; the example above is minified):
https://networksurvey.app/app/watchlist?d=eyJ2IjoxLCJuYW1lIjoiQWNtZSBuZXR3b3JrcyIsImVudHJpZXMiOlt7ImxhYmVsIjoiSFEiLCJzc2lkIjoiSFEtR3Vlc3QifSx7ImxhYmVsIjoiTG9iYnkiLCJic3NpZCI6ImE0OjExOjIyOjMzOjQ0OjFjIn1dfQYou can use this example to verify that your encoder produces the same d value.
Errors and older app versions
Section titled “Errors and older app versions”If a link cannot be imported, the app shows a short message and imports nothing. For example, a link with a newer schema version than the installed app understands shows a message that a newer app version is needed. Malformed or oversized links show a corresponding error message.
Related
Section titled “Related”- Wi-Fi watchlist: what the watchlist does and how to use it
- Intent API: the other programmatic integration for Network Survey