-
Notifications
You must be signed in to change notification settings - Fork 0
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.
Add the api block to your server config.json:
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Enable/disable the API server |
bind |
string | "127.0.0.1:9090" |
Address and port for the API to listen on |
token |
string | "" |
Bearer token for authentication. Required for production. |
⚠️ Security: Always set a strongtokenin production. If empty, 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.
All requests require the Authorization header:
Authorization: Bearer your-secret-api-token
Requests without a valid token receive 401 Unauthorized.
GET /api/server/status
Returns server version, uptime, and user count.
Response:
{
"version": "0.1.70",
"uptime_seconds": 3600,
"total_users": 5,
"status": "running"
}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 /api/users/{key}
Returns statistics for a specific 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 /api/users/{key}
Removes the user and their access key.
PUT /api/users/{key}/limit
Request body:
{
"limit_bytes": 5368709120
}Set to null to remove the limit.
POST /api/users/{key}/reset
Resets bytes_up, bytes_down, and connections to zero.
# 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/resetimport 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']}")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
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
# 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}
{ "mode": "server", "listen": "0.0.0.0:50000", "access_keys": ["..."], "api": { "enabled": true, "bind": "127.0.0.1:9090", "token": "your-secret-api-token" } }