reference/link-handler-spec.md
/link Handler Spec
Status:
implemented- active in
apps/webfortest.mino.ink,mino.ink, and built-in UI
Last updated:
- February 11, 2026
Goal
Support zero-manual onboarding from setup links generated by the server:
- Relay mode:
https://test.mino.ink/link?relayCode=...&relayUrl=...https://mino.ink/link?relayCode=...&relayUrl=...
- Open-port mode:
https://test.mino.ink/link?serverUrl=...&apiKey=...https://mino.ink/link?serverUrl=...&apiKey=...
http://localhost:3000/link?serverUrl=...&apiKey=...(built-in UI)http://localhost:5173/link?serverUrl=...&apiKey=...(local dev)
The user should open the link and be connected automatically.
Required Query Params
- Direct mode:
serverUrlapiKey
- Relay mode:
relayCode- optional
relayUrl(defaults to configured relay base)
Optional (future):
workspacereturnTo
Required Behavior
- Parse query params on
/link. - If
relayCodeis present, exchange at relay:POST {relayUrl}/api/v1/pair/exchange- response contains
serverUrl+apiKey
- Validate presence of resolved
serverUrlandapiKey. - Normalize
serverUrl:- trim whitespace
- remove trailing slash (while preserving path segments)
- Verify key:
POST {serverUrl}/api/v1/auth/verify- header:
X-Mino-Key: {apiKey}
- Mark setup complete:
POST {serverUrl}/api/v1/auth/link- header:
X-Mino-Key: {apiKey}
- Persist linked server profile in localStorage (
mino.linkedServers.v1). - Redirect to
/workspace?profile=<id>.
Error Handling Requirements
- Missing params: show actionable error with retry link.
- Auth failure (
401): show invalid key error and manual form fallback. - Network/CORS failure: show diagnostics (
serverUrl, endpoint attempted). - Any failure must keep manual link form available.
Security Requirements
- Never log raw
apiKeyto console/analytics. - Redact key in UI logs and telemetry.
- Remove sensitive params from URL after processing (replaceState):
apiKeyrelayCoderelayUrl
Acceptance Criteria
- Opening a valid relay or direct
/linkURL performs full linking without user typing. - Successful flow triggers
POST /api/v1/auth/linkexactly once. - URL is cleaned immediately (
apiKeyremoved viahistory.replaceState). - Invalid links fail safely and present manual fallback.
- Behavior is identical on:
https://mino.inkhttps://test.mino.ink- built-in UI (
http://localhost:3000) - local dev client (
http://localhost:5173)