# Local configuration HTTP API

Source: https://onexray.com/docs/advanced/local-api/
Description: Validate OneXray JSON and generate runtime previews through the desktop app's authenticated loopback HTTP API.
Language: en-US
Last updated: 2026-09-28


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.

```json
{
  "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](https://onexray.com/docs/configuration/custom-routing/) with empty entry slots |
| `advanced-routing` | [Advanced Custom JSON](https://onexray.com/docs/configuration/advanced-routing/) within that template's field boundaries |
| `raw` | A [complete Raw JSON](https://onexray.com/docs/configuration/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:

```json
{
  "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](https://onexray.com/docs/ai/) · [Configuration boundaries](https://onexray.com/docs/configuration/compatibility/)


