3x-ui/docs/docs.md
2025-07-30 19:03:45 +05:00

14 KiB

X-UI API Documentation

Overview

This document provides instructions for interacting with the X-UI panel API. The API allows for programmatic management of inbounds (connections), users, and server settings.

Authentication

The API uses a cookie-based session for authentication.

  1. You must first send a POST request to the /login endpoint with your credentials.
  2. If successful, the server will respond with a Set-Cookie header containing a session cookie (e.g., session=...).
  3. Your HTTP client must store this cookie and include it in the Cookie header for all subsequent API requests.

While many headers sent by a browser are not strictly required, including a User-Agent and Referer is good practice to better emulate a real client.

Endpoints

1. Login

Authenticates the user and initiates a session by returning a session cookie.

  • Endpoint: POST {base_url}/login
  • Body: application/x-www-form-urlencoded
Parameter Type Description
username string Your panel username.
password string Your panel password.
  • Success Response (200 OK):
    • The response will include a Set-Cookie header in the HTTP response.
    {
        "success": true,
        "msg": "Login successful",
        "obj": null
    }
    

2. Get All Inbounds

Fetches a list of all configured inbound connections.

  • Endpoint: POST {base_url}/panel/inbound/list

  • Body: None

  • Success Response (200 OK):

    {
        "success": true,
        "msg": "",
        "obj": [
            {
                "id": 1,
                "up": 40912424334,
                "down": 537061968966,
                "total": 0,
                "remark": "My-First-Inbound",
                "enable": true,
                "expiryTime": 0,
                "listen": "YOUR_SERVER_IP",
                "port": 19271,
                "protocol": "vless",
                "settings": "{\"clients\":[{\"id\":\"user-uuid-goes-here\",\"email\":\"user-email-goes-here\",...}]}",
                "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"realitySettings\":{\"privateKey\":\"REALITY_PRIVATE_KEY\",\"settings\":{\"publicKey\":\"REALITY_PUBLIC_KEY\"},...}}",
                "tag": "inbound-YOUR_SERVER_IP:19271",
                "sniffing": "{\"enabled\":false,...}"
            }
        ]
    }
    

3. Get Online Clients

Fetches a list of emails corresponding to currently online clients.

  • Endpoint: POST {base_url}/panel/inbound/onlines
  • Body: None
  • Success Response (200 OK):
    {
        "success": true,
        "msg": "",
        "obj": [
            "client1-email",
            "online-user@example.com"
        ]
    }
    

4. Get New Reality Certificate

Generates a new X25519 key pair for use with VLESS Reality.

  • Endpoint: POST {base_url}/server/getNewX25519Cert
  • Body: None
  • Success Response (200 OK):
    {
        "success": true,
        "msg": "",
        "obj": {
            "privateKey": "a_very_long_private_key_string",
            "publicKey": "a_shorter_public_key_string"
        }
    }
    

5. Add VLESS Reality Inbound

Creates a new VLESS Reality inbound connection.

  • Endpoint: POST {base_url}/panel/inbound/add
  • Body: application/x-www-form-urlencoded

This endpoint requires a complex body where several parameters are URL-encoded JSON strings.

Parameter Description Example Value
remark A name or comment for the inbound. My-Test-Key
listen The server IP address to listen on. Leave empty for all IPs. YOUR_SERVER_IP
port The port to listen on. 0 for a random port. 48673
protocol The protocol type. vless
expiryTime Expiration timestamp in milliseconds. 0 for no expiration. 1753969593148
total Data limit in bytes. 0 for unlimited. 0
settings URL-encoded JSON string with client details (UUID, email, etc.). (See structure below)
streamSettings URL-encoded JSON string with transport and security settings (e.g., Reality). (See structure below)
sniffing URL-encoded JSON string for traffic sniffing settings. {"enabled":false,...}
  • Decoded settings Structure:

    {
      "clients": [
        {
          "id": "a-generated-uuid",
          "email": "a-generated-email",
          "enable": true,
          "flow": "",
          "limitIp": 0,
          "totalGB": 0,
          "expiryTime": 0,
          "subId": "a-generated-sub-id"
        }
      ],
      "decryption": "none",
      "fallbacks": []
    }
    
  • Decoded streamSettings Structure:

    {
      "network": "tcp",
      "security": "reality",
      "realitySettings": {
        "dest": "example.com:443",
        "serverNames": ["example.com", "www.example.com"],
        "privateKey": "THE_PRIVATE_KEY_FROM_STEP_4",
        "publicKey": "THE_PUBLIC_KEY_FROM_STEP_4",
        "shortIds": ["generated_id1", "generated_id2"],
        "fingerprint": "chrome",
        "spiderX": "/"
      }
    }
    
  • Success Response (200 OK): The response object contains the full configuration of the newly created inbound.

    {
        "success": true,
        "msg": "Create Successfully",
        "obj": {
            "id": 16,
            "remark": "Test test",
            "port": 48673,
            "listen": "YOUR_SERVER_IP",
            "settings": "{\"clients\":[{\"id\":\"60f3a042-7f0c-43a5-a9e6-de76f66703dd\",...}]}",
            "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"realitySettings\":{...}}",
            // ... and other fields
        }
    }
    

Code Examples

Python (requests)

The requests.Session object is perfect for this task as it automatically handles cookies across requests.

import requests

# --- Configuration ---
BASE_URL = "http://127.0.0.1:PORT/YOUR_SECRET_PATH"
USERNAME = "your_username"
PASSWORD = "your_password"

# 1. Create a session that will store cookies
session = requests.Session()

# 2. Login to establish the session
try:
    login_url = f"{BASE_URL}/login"
    login_data = {"username": USERNAME, "password": PASSWORD}
    response = session.post(login_url, data=login_data)
    response.raise_for_status()
    
    if response.json().get("success"):
        print("Login successful!")
        
        # 3. Now you can make other API calls with the same session
        inbounds_url = f"{BASE_URL}/panel/inbound/list"
        inbounds_response = session.post(inbounds_url)
        inbounds_data = inbounds_response.json()
        
        print(f"Successfully fetched {len(inbounds_data.get('obj', []))} inbounds.")
    else:
        print(f"Login failed: {response.json().get('msg')}")

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Node.js (axios)

In Node.js, axios does not handle cookies by default. You need to use a cookie jar helper library like axios-cookiejar-support and tough-cookie.

First, install the dependencies: npm install axios axios-cookiejar-support tough-cookie

const axios = require('axios');
const { HttpsCookieAgent } = require('http-cookie-agent/http');
const tough = require('tough-cookie');

// --- Configuration ---
const BASE_URL = 'http://127.0.0.1:PORT/YOUR_SECRET_PATH';
const USERNAME = 'your_username';
const PASSWORD = 'your_password';

async function main() {
    // 1. Create a cookie jar to store session cookies
    const cookieJar = new tough.CookieJar();

    // 2. Create an axios instance that uses the cookie jar
    const apiClient = axios.create({
        httpAgent: new HttpsCookieAgent({ cookies: { jar: cookieJar } }),
        httpsAgent: new HttpsCookieAgent({ cookies: { jar: cookieJar } }),
    });

    try {
        // 3. Login
        console.log('Attempting to log in...');
        const loginUrl = `${BASE_URL}/login`;
        // For x-www-form-urlencoded, use a URLSearchParams object
        const loginData = new URLSearchParams({
            username: USERNAME,
            password: PASSWORD
        });

        const loginResponse = await apiClient.post(loginUrl, loginData);

        if (loginResponse.data.success) {
            console.log('Login successful!');

            // 4. Make another request. The cookie is sent automatically.
            const inboundsUrl = `${BASE_URL}/panel/inbound/list`;
            const inboundsResponse = await apiClient.post(inboundsUrl);
            
            if (inboundsResponse.data.success) {
                console.log(`Successfully fetched ${inboundsResponse.data.obj.length} inbounds.`);
            } else {
                 console.error('Failed to fetch inbounds:', inboundsResponse.data.msg);
            }
        } else {
            console.error('Login failed:', loginResponse.data.msg);
        }
    } catch (error) {
        console.error('An API error occurred:', error.message);
    }
}

main();

Browser JavaScript (fetch)

In a web browser context, fetch can automatically handle cookies if the request is to the same origin, or if you specify credentials: 'include' for cross-origin requests.

// --- Configuration ---
const BASE_URL = 'http://127.0.0.1:PORT/YOUR_SECRET_PATH';
const USERNAME = 'your_username';
const PASSWORD = 'your_password';

async function runApiFlow() {
    try {
        // 1. Login
        console.log('Logging in...');
        const loginResponse = await fetch(`${BASE_URL}/login`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                username: USERNAME,
                password: PASSWORD
            }),
            // This is crucial for the browser to store and send cookies
            credentials: 'include' 
        });

        const loginResult = await loginResponse.json();
        if (!loginResult.success) {
            throw new Error(`Login failed: ${loginResult.msg}`);
        }
        console.log('Login successful!');

        // 2. Fetch inbounds. The browser automatically includes the cookie.
        const inboundsResponse = await fetch(`${BASE_URL}/panel/inbound/list`, {
            method: 'POST',
            credentials: 'include'
        });

        const inboundsResult = await inboundsResponse.json();
        if (inboundsResult.success) {
            console.log(`Found ${inboundsResult.obj.length} inbounds.`);
        } else {
            throw new Error(`Failed to fetch inbounds: ${inboundsResult.msg}`);
        }

    } catch (error) {
        console.error('API Flow Error:', error);
    }
}

runApiFlow();

Generating the VLESS URL

After creating an inbound using the /panel/inbound/add endpoint, you can construct a standard vless:// URL from the obj field in the JSON response.

The URL format is: vless://{UUID}@{ADDRESS}:{PORT}?{PARAMETERS}#{REMARK}

Here is how to map the JSON response fields to the URL components:

URL Part JSON Path from obj Example
UUID settings.clients[0].id (after JSON parsing) 60f3a042-7f0c-43a5-a9e6-de76f66703dd
ADDRESS listen (or your server's domain name) YOUR_SERVER_IP
PORT port 48673
REMARK remark (URL-encoded) Test%20test

Parameters (in the query string):

Parameter JSON Path from obj Description
type streamSettings.network Transport protocol, e.g., tcp.
security streamSettings.security Security layer, e.g., reality.
pbk streamSettings.realitySettings.settings.publicKey The public key for Reality.
fp streamSettings.realitySettings.settings.fingerprint The browser fingerprint, e.g., chrome.
sni streamSettings.realitySettings.serverNames[0] The Server Name Indication to use.
sid streamSettings.realitySettings.shortIds[0] The first short ID from the list.
spx streamSettings.realitySettings.settings.spiderX The SpiderX path.