Management API
OSTP includes a built-in REST API for remote server management. This API enables third-party panels (like 3x-ui), Telegram bots, and custom dashboards to manage users, monitor traffic, and control the server.
Enabling the API
Add an api inbound to your server config.json's inbounds array:
{
"mode": "server",
"inbounds": [
{
"type": "api",
"tag": "api-in",
"listen": "127.0.0.1",
"port": 9090,
"token": "your-secret-api-token"
}
]
}
| Field | Type | Default | Description |
|---|---|---|---|
type |
string | required | Must be "api" |
listen |
string | required | Address for the API to listen on (e.g. "127.0.0.1") |
port |
u16 | required | Port for the API to listen on (e.g. 9090) |
token |
string | null |
Bearer token for authentication. Required for production. |
⚠️ Security: Always set a strong
tokenin production. If omitted, the API assumes a trusted local environment.
💡 Tip: Bind to
127.0.0.1and use a reverse proxy (nginx/caddy) with TLS for remote access.
Authentication
All requests require the Authorization header:
Authorization: Bearer your-secret-api-token
Requests without a valid token receive 401 Unauthorized.
Endpoints
Server Status
GET /api/server/status
Returns server version, uptime, and user count.
Response:
{
"version": "0.1.70",
"uptime_seconds": 3600,
"total_users": 5,
"status": "running"
}
List Users
GET /api/users
Returns all users with traffic statistics.
Response:
{
"users": [
{
"key": "c8a6fde902b4e23910cde882b7cf1612",
"bytes_up": 1048576,
"bytes_down": 52428800,
"connections": 3,
"limit_bytes": 10737418240
}
]
}
Get User Stats
GET /api/users/{key}
Returns statistics for a specific user.
Create User
POST /api/users
Request body (optional):
{
"key": "custom-key-or-leave-empty-for-auto",
"limit_bytes": 10737418240
}
If key is omitted, a secure random key is generated automatically.
Response:
{
"key": "a1b2c3d4e5f6...",
"created": true
}
Delete User
DELETE /api/users/{key}
Removes the user and their access key.
Set Traffic Limit
PUT /api/users/{key}/limit
Request body:
{
"limit_bytes": 5368709120
}
Set to null to remove the limit.
Reset Traffic Counters
POST /api/users/{key}/reset
Resets bytes_up, bytes_down, and connections to zero.
Examples
cURL
# Server status
curl -s -H "Authorization: Bearer mytoken" \
http://127.0.0.1:9090/api/server/status | jq
# List all users
curl -s -H "Authorization: Bearer mytoken" \
http://127.0.0.1:9090/api/users | jq
# Create user with 10 GB limit
curl -s -X POST \
-H "Authorization: Bearer mytoken" \
-H "Content-Type: application/json" \
-d '{"limit_bytes": 10737418240}' \
http://127.0.0.1:9090/api/users | jq
# Delete user
curl -s -X DELETE \
-H "Authorization: Bearer mytoken" \
http://127.0.0.1:9090/api/users/c8a6fde902b4e23910cde882b7cf1612
# Set 5 GB limit
curl -s -X PUT \
-H "Authorization: Bearer mytoken" \
-H "Content-Type: application/json" \
-d '{"limit_bytes": 5368709120}' \
http://127.0.0.1:9090/api/users/c8a6fde902b4e23910cde882b7cf1612/limit
# Reset counters
curl -s -X POST \
-H "Authorization: Bearer mytoken" \
http://127.0.0.1:9090/api/users/c8a6fde902b4e23910cde882b7cf1612/reset
Python
import requests
API = "http://127.0.0.1:9090"
TOKEN = "your-secret-api-token"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
# List users
users = requests.get(f"{API}/api/users", headers=HEADERS).json()
for user in users["users"]:
print(f"Key: {user['key'][:8]}... | ↑{user['bytes_up']} ↓{user['bytes_down']}")
# Create user
resp = requests.post(f"{API}/api/users", headers=HEADERS,
json={"limit_bytes": 10 * 1024**3})
print(f"New key: {resp.json()['key']}")
Integration with Panels
The API is designed to be compatible with panel architectures like 3x-ui and RemnaWave. A panel integration typically:
- Calls
POST /api/usersto create access keys for new subscribers - Periodically polls
GET /api/usersfor traffic consumption - Uses
PUT /api/users/{key}/limitto enforce data caps - Calls
DELETE /api/users/{key}when a subscription expires
Subscription API
Get Client Configuration
GET /api/subscribe/{access_key}
Returns a ready-to-use client configuration for the given access key. No Bearer token required -- the access key itself authenticates the request.
Default response (Accept: application/json):
{
"ok": true,
"data": {
"mode": "client",
"server": "example.com:50000",
"access_key": "c8a6fde902b4e23910cde882b7cf1612",
"socks5_bind": "127.0.0.1:1088",
"tun": {"enable": false, "dns": "1.1.1.1"},
"turn": {"enabled": false},
"mux": {"enabled": false, "sessions": 1},
"debug": false
}
}
Share link response (Accept: text/plain):
ostp://c8a6fde902b4e23910cde882b7cf1612@example.com:50000
Examples
# Get client config JSON
curl -s http://127.0.0.1:9090/api/subscribe/c8a6fde902b4e23910cde882b7cf1612 | jq
# Get share link
curl -s -H "Accept: text/plain" \
http://127.0.0.1:9090/api/subscribe/c8a6fde902b4e23910cde882b7cf1612
# Use with sub-store / NekoBox
# Set subscription URL to: http://your-server:9090/api/subscribe/{key}