Deep Link Import
What this is
Section titled “What this is”Clash for AI supports a desktop deep link import flow.
Third-party websites can open the desktop app with a URL like:
clash-for-ai://v1/import?resource=provider&payload=BASE64URL_JSONThe desktop app will:
- open or bring the existing window to the front,
- parse the import request,
- show an import confirmation dialog,
- import the data only after the user confirms.
The current minimum scope supports:
providermodel
If you want a ready-to-use generator page, open:
URL format
Section titled “URL format”Use this structure:
clash-for-ai://v1/import?resource=<provider|model>&payload=<base64url-json>Rules:
resourcemust beproviderormodelpayloadmust be a base64url-encoded JSON object- the app will reject unsupported routes, invalid payloads, or missing required fields
Local verification
Section titled “Local verification”If you want to verify this flow on your own machine, use a packaged desktop build instead of relying only on pnpm dev.
Why:
- browsers ask the operating system to open
clash-for-ai://... - the operating system needs a registered handler for that scheme
- the packaged app declares that handler reliably
- a dev process alone is often not enough to make the browser recognize the scheme
Recommended verification steps:
- build a local packaged desktop app
- launch the packaged app at least once
- open /deeplink.html
- click
Open Deep Link - confirm that Clash for AI opens and shows the import confirmation dialog
If the browser reports that the scheme has no registered handler, the most common reason is that the packaged app has not been installed or launched yet.
Provider payload
Section titled “Provider payload”Supported fields:
{ "name": "OpenRouter", "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "sk-or-example"}Notes:
name,baseUrl, andapiKeyare required- this public payload is intentionally aligned with the current desktop add form
- third-party integrators do not need to provide an auth mode field for the minimum import flow
- Clash for AI currently treats imported Provider links with the default bearer-style behavior used by the existing add form
Example deep link:
clash-for-ai://v1/import?resource=provider&payload=eyJuYW1lIjoiT3BlblJvdXRlciIsImJhc2VVcmwiOiJodHRwczovL29wZW5yb3V0ZXIuYWkvYXBpL3YxIiwiYXBpS2V5Ijoic2stb3ItZXhhbXBsZSJ9Model payload
Section titled “Model payload”Supported fields:
{ "name": "Relay Models", "baseUrl": "https://relay.example.com/v1", "apiKey": "sk-model-example", "providerType": "openai-compatible", "modelIds": ["gpt-4o-mini", "claude-3-7-sonnet"]}Notes:
name,baseUrl,apiKey, and at least one model id are requiredproviderTypeis optional- supported
providerTypevalues are:openai-compatibleanthropic-compatible - if
providerTypeis omitted, Clash for AI defaults toopenai-compatible - the first model in
modelIdsbecomes the default model id
Example deep link:
clash-for-ai://v1/import?resource=model&payload=eyJuYW1lIjoiUmVsYXkgTW9kZWxzIiwiYmFzZVVybCI6Imh0dHBzOi8vcmVsYXkuZXhhbXBsZS5jb20vdjEiLCJhcGlLZXkiOiJzay1tb2RlbC1leGFtcGxlIiwicHJvdmlkZXJUeXBlIjoib3BlbmFpLWNvbXBhdGlibGUiLCJtb2RlbElkcyI6WyJncHQtNG8tbWluaSIsImNsYXVkZS0zLTctc29ubmV0Il19How to build the payload
Section titled “How to build the payload”The payload is:
- a JSON object
- UTF-8 encoded
- base64url encoded
Base64url means:
- replace
+with- - replace
/with_ - remove trailing
=
Example in JavaScript:
function toBase64Url(value) { return btoa(JSON.stringify(value)) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/g, "");}
const payload = toBase64Url({ name: "OpenRouter", baseUrl: "https://openrouter.ai/api/v1", apiKey: "sk-or-example"});
const url = `clash-for-ai://v1/import?resource=provider&payload=${payload}`;User experience
Section titled “User experience”When a user clicks the deep link:
- the system asks whether to open Clash for AI,
- Clash for AI opens,
- the app shows an import confirmation dialog,
- the user confirms or cancels,
- the app imports the configuration only after confirmation.
Security notes
Section titled “Security notes”Do not treat this flow as silent import.
Recommended practices:
- always expect a user confirmation step
- do not publicly expose real API keys in shared links
- prefer short-lived or user-generated links when possible
- validate
baseUrland payload fields on the sender side too
Current limitations
Section titled “Current limitations”This minimum implementation does not yet support:
provider + modelscombined import- signed payloads
- remote config fetch by token
- automatic overwrite or merge strategies