NeuroAgent

How to Get User Data Through 3x-ui API

Complete guide to retrieving user data through 3x-ui API, including client IP addresses. Troubleshooting endpoints and panel configuration.

How to get user data through the 3x-ui API?

Hello! I have several servers with the 3x-ui panel, and I’m trying to automate some processes. When attempting to get a list of client IP addresses through the API:

python
session.post(f"{panel_url}/panel/api/inbounds/clientIps/{client_email}", verify=False)

I receive the response: {'success': True, 'msg': '', 'obj': 'No IP Record'}.

However, in the server logs, I can see many entries with IP addresses for this client:

grep "email: 011igg6e" /usr/local/x-ui/access.log

Output:

2025/11/01 06:22:48.053123 from **ip**:57758 accepted tcp:8.8.4.4:443 [inbound-443 >> direct] email: 011igg6e
2025/11/01 06:22:48.144394 from **ip**:57757 accepted udp:192.168.0.119:22000 [inbound-443 -> blocked] email: 011igg6e

At the same time, other API requests, such as getting the list of inbounds, work successfully. I also get empty responses when trying to request system logs or connection logs.

My panel configuration:

json
"log": {
    "access": "./access.log",
    "dnsLog": false,
    "error": "./error.log",
    "loglevel": "warning",
    "maskAddress": ""
  },
  "api": {
    "tag": "api",
    "services": [
      "HandlerService",
      "LoggerService",
      "StatsService"
    ]
  },

Could I have incorrect panel settings? I worked with the API based on this guide: https://www.postman.com/hsanaei/3x-ui/documentation

NeuroAgent

Hello! To retrieve user data through the 3x-ui API, including client IP addresses, you need to use the correct endpoints and ensure your panel configuration is set up properly. The main issue you’re encountering is that the endpoint /panel/api/inbounds/clientIps/{client_email} doesn’t exist or doesn’t return data due to incorrect logging or API services configuration.


Table of Contents


Main 3x-ui API Endpoints

3x-ui provides a RESTful API for server management. The main endpoints you’ll need are:

  • Authentication: /panel/api/login - get session token
  • Inbounds: /panel/api/inbounds - list of all inbounds
  • Clients: /panel/api/inbounds/clients - list of clients
  • Client IPs: /panel/api/inbounds/clientIps/{clientId} - get client IP addresses

It’s important to note that the endpoint for retrieving client IP addresses requires clientId, not client_email. According to the documentation, clientId is the unique identifier for each client.


How to Get Client IP Addresses

To retrieve client IP addresses through the API, follow these steps:

1. Get the list of clients

First, get the list of all clients to find the one you need by email:

python
import requests

# Get the list of clients
response = session.get(f"{panel_url}/panel/api/inbounds/clients")
if response.json()['success']:
    clients = response.json()['obj']
    # Find the client by email
    target_client = next((c for c in clients if c.get('email') == '011igg6e'), None)
    if target_client:
        client_id = target_client['id']

2. Get the client’s IP addresses

Use the obtained clientId to request IP addresses:

python
# Get client IP addresses
response = session.get(f"{panel_url}/panel/api/inbounds/clientIps/{client_id}")
if response.json()['success']:
    ip_addresses = response.json()['obj']
    print(f"Client IP addresses: {ip_addresses}")

3. Alternative method through access.log

If the API doesn’t return data as in your case, you can directly read the access logs:

python
import re
from datetime import datetime, timedelta

def get_client_ips_from_log(email, log_path="/usr/local/x-ui/access.log", hours=24):
    """Get client IP addresses from access logs"""
    since_time = (datetime.now() - timedelta(hours=hours)).strftime("%Y/%m/%d %H:%M:%S.%f")[:-3]
    
    pattern = rf"{email}$"
    ips = set()
    
    try:
        with open(log_path, 'r') as f:
            for line in f:
                if email in line and line.split()[0] >= since_time:
                    # Extract IP address from log
                    ip_match = re.search(r'from (\d+\.\d+\.\d+\.\d+):', line)
                    if ip_match:
                        ips.add(ip_match.group(1))
    except FileNotFoundError:
        print(f"Log file not found: {log_path}")
    
    return list(ips)

Panel Configuration Setup

Your current API configuration may not include the necessary services for working with logs. In the "api" section, ensure that LoggerService is enabled:

json
{
  "log": {
    "access": "./access.log",
    "dnsLog": false,
    "error": "./error.log",
    "loglevel": "warning",
    "maskAddress": ""
  },
  "api": {
    "tag": "api",
    "services": [
      "HandlerService",
      "LoggerService",
      "StatsService"
    ]
  }
}

It’s important that LoggerService is enabled for accessing logs through the API. As noted in the documentation, without this service, endpoints related to logs may not work.


API Authentication

Before making API requests, you need to authenticate:

python
import requests

url = "https://your-panel-ip:port"
username = "your_username"
password = "your_password"

# Get session token
login_response = requests.post(
    f"{url}/panel/api/login",
    json={"username": username, "password": password},
    verify=False
)

if login_response.json()['success']:
    token = login_response.json()['obj']
    # Set header for subsequent requests
    headers = {"Authorization": f"Bearer {token}"}
    session = requests.Session()
    session.headers.update(headers)

Alternative Data Retrieval Methods

1. Using the 3x-ui-js library

There’s a JavaScript library for working with the 3x-ui API. According to the repository, it provides a getClientIps(clientId) method:

javascript
// Example using the library
const { Xui } = require('3x-ui-js');

const xui = new Xui('panel-host', 443, '/panel', false);
await xui.login('username', 'password');

const clientIps = await xui.getClientIps('clientId');
console.log('Client IP addresses:', clientIps);

2. Direct database access

If the API isn’t working, you can directly access the SQLite database:

python
import sqlite3
import json

def get_client_ips_from_db(db_path="/usr/local/x-ui/db/x-ui.db", client_email="011igg6e"):
    """Get IP addresses from database"""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    # Get client by email
    cursor.execute("SELECT id FROM clients WHERE email = ?", (client_email,))
    client = cursor.fetchone()
    
    if not client:
        return []
    
    client_id = client[0]
    
    # Get IP addresses (if table exists)
    try:
        cursor.execute("SELECT ip FROM client_ips WHERE client_id = ?", (client_id,))
        ips = [row[0] for row in cursor.fetchall()]
    except sqlite3.OperationalError:
        print("client_ips table does not exist")
        ips = []
    
    conn.close()
    return ips

Debugging and Troubleshooting

1. Check endpoints

Ensure that the endpoints are available and returning the correct data:

python
# Check endpoint availability
response = session.get(f"{panel_url}/panel/api/inbounds/clientIps/test")
print(response.json())  # Should return an error, not 'No IP Record'

2. Check access permissions

Ensure that the user you’re making the request on behalf of has the necessary permissions. According to the documentation, the API requires authentication and appropriate permissions.

3. Check data format

Ensure that clientId has the correct format. It’s usually a numeric identifier:

python
# Check client list to get the correct clientId format
response = session.get(f"{panel_url}/panel/api/inbounds/clients")
clients = response.json()['obj']
for client in clients:
    print(f"Email: {client.get('email')}, ID: {client.get('id')}")

Python Code Examples

Complete example for getting client IP addresses

python
import requests
import re
from datetime import datetime, timedelta

class XUIClient:
    def __init__(self, panel_url, username, password):
        self.panel_url = panel_url
        self.username = username
        self.password = password
        self.token = None
        self.session = requests.Session()
        self.session.verify = False
        
    def login(self):
        """Login to panel and get token"""
        response = self.session.post(
            f"{self.panel_url}/panel/api/login",
            json={"username": self.username, "password": self.password}
        )
        
        if response.json()['success']:
            self.token = response.json()['obj']
            self.session.headers.update({"Authorization": f"Bearer {self.token}"})
            return True
        return False
    
    def get_client_by_email(self, email):
        """Get client by email"""
        response = self.session.get(f"{self.panel_url}/panel/api/inbounds/clients")
        
        if response.json()['success']:
            clients = response.json()['obj']
            return next((c for c in clients if c.get('email') == email), None)
        return None
    
    def get_client_ips_api(self, client_id):
        """Get IP addresses through API"""
        response = self.session.get(f"{self.panel_url}/panel/api/inbounds/clientIps/{client_id}")
        
        if response.json()['success']:
            return response.json()['obj']
        return []
    
    def get_client_ips_from_log(self, email, hours=24):
        """Get IP addresses from logs"""
        since_time = (datetime.now() - timedelta(hours=hours)).strftime("%Y/%m/%d %H:%M:%S")[:-3]
        log_path = "/usr/local/x-ui/access.log"
        
        pattern = rf"email: {email}$"
        ips = set()
        
        try:
            with open(log_path, 'r') as f:
                for line in f:
                    if email in line and line.split()[0] >= since_time:
                        ip_match = re.search(r'from (\d+\.\d+\.\d+\.\d+):', line)
                        if ip_match:
                            ips.add(ip_match.group(1))
        except FileNotFoundError:
            print(f"Log file not found: {log_path}")
        
        return list(ips)
    
    def get_client_ips(self, email, use_api_first=True):
        """Main method for getting client IP addresses"""
        # Get client by email
        client = self.get_client_by_email(email)
        if not client:
            return []
        
        # Try through API first
        if use_api_first:
            ips = self.get_client_ips_api(client['id'])
            if ips and ips != 'No IP Record':
                return ips
        
        # If API didn't work, read logs directly
        return self.get_client_ips_from_log(email)

# Usage
client = XUIClient("https://your-panel:443", "username", "password")
if client.login():
    ips = client.get_client_ips("011igg6e")
    print(f"Found IP addresses: {ips}")

Conclusion

To retrieve user data through the 3x-ui API, you need to:

  1. Use the correct API endpoints, including /panel/api/inbounds/clientIps/{clientId}
  2. Ensure that LoggerService is enabled in your panel configuration
  3. Properly handle authentication through session tokens
  4. If API issues arise, use alternative methods: direct log reading or database access

The main issues you’re encountering are related to using the wrong endpoint (email instead of clientId) and possible incorrect API services configuration. It’s recommended to check your current version of 3x-ui and ensure you’re using up-to-date API documentation.

Sources

  1. 3X-UI Configuration Documentation - GitHub Wiki
  2. 3X-UI API Documentation - Postman Network
  3. 3X-UI JS Client Library - GitHub
  4. 3X-UI Client Management - DeepWiki
  5. 3X-UI Inbound Management - DeepWiki
  6. 3X-UI Installation Guide - SpaceCore Wiki