Skip to content
Local configuration HTTP API

Local configuration HTTP API

Trusted local tools can reuse the desktop app’s configuration parser, compiler, installed GeoData, and libXray validation. No separate CLI is required. The API does not import or save assets, change settings, download dependencies, or start and stop VPN.

Enable and authenticate

Open Advanced → Xray → Local API, enable it, and save. It is off by default and available only on desktop. The app must remain running and finish service preparation; hiding its window is fine, but quitting the app stops the API even if VPN stays connected.

The default address is http://127.0.0.1:18587. Choose a port from 1024 to 65535. It listens only on IPv4 loopback, never a LAN address. Automatic Xray SOCKS/metrics ports avoid the saved API port even while the API is disabled. User-written inbound ports are not rewritten.

Copy the Token from the app into a trusted local tool’s protected credential storage. Every request requires Authorization: Bearer <token>. The Token survives restarts; resetting it immediately revokes the old value. Disabling the API retains it. Clearing app data removes it, and connection backups do not contain it.

Do not put the Token in an AI prompt, URL, command-line argument, source repository, or log. Configure credentials separately from the text you ask an AI to generate. Connect directly to the displayed loopback address, bypass environment proxies, and disable redirects. Browser-origin requests and cross-origin access are not supported. Authentication is not protection against malware already controlling your account.

API version 1

Method and path Result
GET /api/v1/info API, app, and Core versions; host platform and supported configuration kinds
POST /api/v1/config/validate App parsing and validation projection, followed by libXray configuration validation
POST /api/v1/config/compile Generated runtime configuration preview, without kernel validation or execution

POST bodies use Content-Type: application/json and are limited to 16 MiB. Supply the original configuration as a text string, not a parsed/re-encoded object, so diagnostic positions refer to the original input.

{
  "kind": "raw",
  "text": "{\n  \"name\": \"Direct example\",\n  \"outbounds\": [{\"protocol\": \"freedom\", \"tag\": \"direct\"}]\n}"
}

This example has no proxy credentials and uses direct access; it is not a supplied VPN server.

kind Meaning of text
outbound One outbound object, as in the node editor; not a document wrapping outbounds
routing Ordinary Custom Routing with empty entry slots
advanced-routing Advanced Custom JSON within that template’s field boundaries
raw A complete Raw JSON configuration

An optional name follows the selected input type’s naming rules; do not confuse a configuration name with an outbound tag. validate rejects options and extra outbounds. Routing validation uses placeholder outbounds, not your actual selected nodes.

Compile a preview

For compile, include kind, text, and an explicit options object:

{
  "platform": "macos",
  "sessionDirectory": "/explicit/preview-directory",
  "metricsPort": 19001,
  "socksPort": 19002,
  "ipv6": true
}
  • platform: ios, macos, android, windows, or linux. This is a configuration target, not a request to run remotely.
  • Windows also needs windowsMode: "exe" or "msix". Windows/Linux require interfaceName.
  • routing and advanced-routing also need a top-level outbounds array containing actual nodes, one per empty entry slot. outbound and raw use their own nodes and reject an extra array.
  • Optional tunDnsIpv4Address, tunDnsIpv6Address, logEnabled, logFilesSupported, logLevel, dnsLog, and maskAddress follow the compiler’s defaults when omitted; they do not inherit the user’s current connection settings.
  • GeoData paths refer to this app’s installed directory. Cross-platform output does not make those paths available on another device. Compilation does not check free ports or existing interfaces, create the session directory, or write the active configuration.

Read the result correctly

Check both status (passed, failed, notRun) and stage (input, compile, kernel). HTTP 200 does not mean validation passed, and passed at compile means only that a preview was generated.

Diagnostics contain a code and message, with path, offset, line, or column only when reliable. Offsets start at 0; lines and columns start at 1. Offsets and columns count UTF-16 code units. A path is an array such as ["routing", "rules", 0, "domain"]. Do not infer a source position from an unlocated Core error or from generated JSON.

validationConfig and compiledConfig are JSON text and may contain credentials. Protect saved results. Read limitations before claiming success. A busy request returns 409, an oversized request 413, and unavailable service 503; none means the configuration passed.

Validation constructs and closes a Core instance without starting VPN. It can have process-level side effects and is not a sandbox for untrusted configurations. It does not download missing GeoData, check database name/quantity constraints, prove the actual node combination, or guarantee startup and connectivity. A client timeout does not cancel native validation: do not automatically retry it.

Generate configurations with AI · Configuration boundaries

Last updated on