Skip to content

Links and deep links

mins understands four kinds of links: server links (one server each), subscription add links, routing links, and https:// redirect links for places that only allow HTTPS (Telegram buttons). Whatever the source, a link never changes anything silently: the app always shows a preview and waits for the user to confirm.

Scheme Protocol Notes
vless:// VLESS TLS, REALITY or none; raw, WebSocket, gRPC, XHTTP, HTTPUpgrade, mKCP.
hysteria2://, hy2:// Hysteria2 Salamander obfuscation, port hopping, certificate pinning.
wireguard:// WireGuard and AmneziaWG AmneziaWG parameters are plain query parameters.
vpn:// AmneziaWG Amnezia’s exported container.
any other (vmess://, trojan://, ss://, …) not supported The link stays in the list as an unsupported server with the reason “Protocol X is not supported”.

Common rules for all server links:

  • Name is the fragment after #, percent-encoded. A flag emoji at its start sets the country (see The mins block).
  • Description goes inside the fragment: #Finland?serverDescription=<base64 of UTF-8 text>. If the base64 contains +, / or =, percent-encode them or use the URL-safe alphabet.
  • Credentials (the part before @) must be percent-encoded. A second @ in them is an error.
  • IPv6 hosts are written in brackets. Ports are 1 to 65535.
  • Query parameter names are case-sensitive. An unknown parameter is ignored with a warning; a repeated or empty parameter name is an error.
vless://<uuid>@<host>:<port>?<params>#<name>
Parameter Value Notes
type raw (alias tcp), ws, grpc, xhttp, httpupgrade, kcp (alias mkcp) Default raw. http, h2, h3 and quic are rejected with “Transport removed; use XHTTP”.
security none, tls, reality Default none. REALITY does not work with ws, httpupgrade or kcp.
encryption string Default none. Must not be empty.
flow string For example xtls-rprx-vision.
sni host name Default: the link’s host.
fp fingerprint Default chrome. Required for REALITY.
alpn comma-separated list For example h2,http/1.1.
ech string ECH config list.
pcs string Pinned peer certificate SHA-256.
vcn string Verify the peer certificate by this name.
pbk string REALITY public key. Required for REALITY.
sid string REALITY short id.
pqv string REALITY ML-DSA-65 verification key.
spx string REALITY spider X.
path string ws, httpupgrade, xhttp; default /. For raw with headerType=http, the request path.
host string ws, httpupgrade, xhttp; for raw with headerType=http, the Host header.
mode gRPC: gun (default), multi. XHTTP: auto (default), packet-up, stream-up, stream-one gRPC guna is parsed but the server is marked unsupported (“gRPC guna uses a custom codec not supported by Xray; use gun or multi”).
serviceName, authority string gRPC.
extra JSON object XHTTP extra settings.
mtu, tti integer mKCP.
seed string mKCP.
headerType string mKCP header type, or http for raw.
fm JSON finalmask settings.
mux JSON Mux settings of this outbound.
fragment length,interval,packets[,maxSplit] TLS fragmentation of this server, for example 50-100,10-20,tlshello.
noises type,packet,delay[,applyTo] joined by ; Noise packets of this server.
allowInsecure, insecure true, false, 1, 0 Disables certificate verification. Sending both is an error. The server shows a warning tag.
testpre, testseed JSON or string Passed to the user record unchanged.
node_id, xtls any Accepted and ignored.

sni, fp, alpn and path must not be present with an empty value.

vless://11111111-1111-4111-8111-111111111111@fi.example.com:443?type=raw&security=reality&sni=www.example.com&fp=chrome&pbk=AbCdEfGhIjKlMnOpQrStUvWxYz0123456789_-abcde&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#Finland%20Reality
vless://11111111-1111-4111-8111-111111111111@xh.example.com:443?type=xhttp&security=tls&sni=xh.example.com&host=xh.example.com&path=%2Fx&mode=auto&alpn=h2#XHTTP
vless://11111111-1111-4111-8111-111111111111@fi.example.com:443?type=grpc&security=tls&serviceName=svc&mode=multi#gRPC
hysteria2://<auth>@<host>[:<port>]/?<params>#<name>

hy2:// is the same. The port defaults to 443. The authentication string may be empty.

Parameter Value Notes
sni host name TLS server name.
pinSHA256 string One pinned certificate fingerprint.
ech string ECH config list.
insecure, allowInsecure true, false, 1, 0 Disables certificate verification. Sending both is an error.
obfs salamander The only supported obfuscation; any other value is an error.
obfs-password string Required with obfs.
mport ports Port hopping range or list, such as 20000-30000 or 443,500-600. A reversed range is an error.
mportHopInt seconds Hop interval: 30, 30s or a range 20-40. At least 5; default 30. Used when mport hops.
hysteria2://s3cret@de.example.com:443/?sni=de.example.com&obfs=salamander&obfs-password=pass#Germany
hy2://s3cret@de.example.com:443/?sni=de.example.com&mport=20000-30000&mportHopInt=30#Germany%20hop

Links with the hysteria2+realm scheme are rejected: “Hysteria realm is not supported”.

wireguard://<private key>@<host>:<port>?publickey=<key>&address=<cidr>[&...]#<name>

Percent-encode the private key: base64 contains +, / and =.

Parameter Value Notes
publickey base64 key Required.
presharedkey base64 key
address comma-separated CIDRs The tunnel addresses, for example 10.0.0.2/32.
dns comma-separated IPs
mtu integer
allowedips comma-separated CIDRs Default 0.0.0.0/0,::/0.
keepalive integer or range Persistent keepalive, seconds.
reserved three bytes 1,2,3 or base64.
jc, jmin, jmax, s1 to s4, h1 to h4, i1 to i5 numbers, ranges (h1..h4), strings (i1..i5) AmneziaWG obfuscation. jmin must not exceed jmax; h1 to h4 ranges must not overlap.
headerprotectionkey, contentpaddingaddition, randomtrailers, disablecookies AmneziaWG extensions (randomtrailers, disablecookies are booleans). headerprotectionkey requires s1 to s4 of at least 12.
rekeyaftertime, rekeytimeout, rejectaftertime, keepalivetimeout, maxhandshakeattempts, persistentkeepalive numbers AmneziaWG timers.
wireguard://AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE%3D@nl.example.com:51820?publickey=AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI%3D&address=10.0.0.2%2F32&dns=1.1.1.1&mtu=1280&jc=4&jmin=40&jmax=70&s1=15&s2=18#Netherlands

A subscription URL (or pasted text, or a file) may also be a single WireGuard or AmneziaWG INI file. It must start with [Interface] (with a required PrivateKey) followed by one or more [Peer] sections (each with Endpoint, up to 256 peers). Keys are case-insensitive; comments start with # or ;.

[Interface]
PrivateKey = AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=
Address = 10.0.0.2/32
DNS = 1.1.1.1
MTU = 1280
Jc = 4
Jmin = 40
Jmax = 70
[Peer]
PublicKey = AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=
Endpoint = nl.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

vpn://<base64> is the link that the Amnezia client exports. mins reads the AmneziaWG container inside it (a zlib-compressed JSON with a 4-byte length prefix, up to 16 MiB), takes the nested last_config, replaces $PRIMARY_DNS and $SECONDARY_DNS with dns1 and dns2 and uses description as the server name. A vpn:// link without an AmneziaWG container is rejected.

A link that opens the normal “add subscription” flow for a URL. Three forms are accepted:

mins://add/https://sub.example.com/abc?token=1
happ://add/https://sub.example.com/abc?token=1
incy://add/https://sub.example.com/abc?token=1
  • <url> is taken as written if it starts with http:// or https://. Otherwise it is percent-decoded once, so mins://add/https%3A%2F%2Fsub.example.com%2Fabc works too.
  • Only mins:// is registered with the operating system (Android, iOS, macOS, Windows and Linux), so only mins:// opens the app from a browser or another app. happ://add/ and incy://add/ are accepted when the user pastes them, scans them as a QR code or opens them from a file.
  • The link starts the same flow as pasting the URL: HTTPS is required, plain HTTP only after the user confirms, then the subscription is fetched and shown in a preview, including any settings that need approval. The user taps Confirm import. There is never a silent import.
  • For QR codes, encode the mins://add/... link as the QR text.

Other mins:// addresses: mins://open only brings the app to the front (the widgets use it), and the routing links below.

Link Effect
mins://routing/add/<payload> Saves a routing profile.
mins://routing/onadd/<payload> Saves it and makes it the active profile.
mins://routing/off Turns the active routing profile off.

happ://routing/... and incy://routing/... with add or onadd are accepted the same way, and incy://autorouting/add|onadd/... too. They work from the clipboard, a QR code, pasted text, a file, the routing header or a line in a subscription body; only mins:// is registered with the system.

<payload> is one of:

  • base64 of the routing profile JSON (any base64 alphabet, padded or not). To build one: base64 -w0 profile.json | tr '+/' '-_' | tr -d '='.
  • an https:// URL, percent-encoded. The app downloads the profile (no redirects; 9 s to connect, 20 s to receive) and shows it in the preview. Profiles added from a URL are downloaded again every time the app starts, keeping their name. Any other scheme, including http://, is rejected with “Routing profile URL must use HTTPS”.
mins://routing/onadd/https%3A%2F%2Fexample.com%2Frouting%2Fru.json
mins://routing/add/eyJOYW1lIjoiRXhhbXBsZSIsIkdsb2JhbFByb3h5IjpmYWxzZX0
mins://routing/off

The profile format is in Routing profiles.

Telegram buttons and other HTTPS-only places

Section titled “Telegram buttons and other HTTPS-only places”

Telegram’s inline buttons accept only https:// URLs, not custom schemes, so a button cannot point to mins://add/... directly. Use the redirector at https://sr.minsclient.com: it is a static page that immediately opens mins with the link you give it.

https://sr.minsclient.com/#add/https://sub.example.com/abc

The link is read from the fragment (the part after #). Browsers never send the fragment to the server, so the subscription URL, which usually contains the user’s token, stays on the device.

Input Meaning
https://sr.minsclient.com/#add/<url> Add subscription <url>.
https://sr.minsclient.com/#mins://add/<url> Same, with the scheme written out.
https://sr.minsclient.com/#routing/add/<payload>, #routing/onadd/<payload>, #routing/off (also with a leading mins://) Routing links.
https://sr.minsclient.com/?url=<percent-encoded mins link> Fallback for senders that drop fragments, for example ?url=mins%3A%2F%2Fadd%2Fhttps%3A%2F%2Fsub.example.com%2Fabc.

Only these actions are accepted, and an add target must be https://. Anything else (other schemes, javascript:, http:// targets, links longer than 8 KiB) is rejected: the page shows “This is not a mins link” and does not navigate.

What happens on a valid link: the page redirects at once, passing the subscription address in percent-encoded form, so characters such as #, ; and & inside it survive. On Android it opens an intent:// URL for the mins app and, if mins is not installed, falls back to the download page at https://minsclient.com/#download; on other systems it opens mins://.... Some browsers block the automatic jump (Telegram’s built-in browser, iOS), so the page also shows a large Open in mins button and a No mins? Download link. The page is shown in Russian or English by the browser’s language and loads no external resources.

A Telegram Bot API message with an inline button (reply_markup):

{
"chat_id": 123456789,
"text": "Your subscription is ready.",
"reply_markup": {
"inline_keyboard": [
[
{
"text": "Add to mins",
"url": "https://sr.minsclient.com/#add/https://sub.example.com/abc"
}
]
]
}
}

Send it to https://api.telegram.org/bot<token>/sendMessage with Content-Type: application/json.

What Why
Encrypted happ://crypt... and incy://crypt... links Rejected: “Encrypted Happ/INCY links are not supported”. Send a normal link or a subscription URL.
Server links of other protocols (vmess://, trojan://, ss://, tuic://, …) Not implemented by the engine. The link is kept as an unsupported server with the reason “Protocol X is not supported”.
hysteria2+realm:// “Hysteria realm is not supported”.
VLESS transports http, h2, h3, quic Removed in Xray; use XHTTP.
Clash and sing-box formats Only Xray configuration imports are supported.
Importing with no preview Every link, QR code and deep link ends in a confirmation screen.
Custom schemes other than mins:// as system links Only mins:// is registered, so as not to clash with Happ or INCY installed on the same device.

Link-type headers (support-url, announce-url and so on) accept https://, and for six of them also mins://; a mins:// link there opens the import preview, never imports directly. See Response headers.