Base URLs
https://admin.vsl247.com
https://admin2.vsl247.com
Authorization
Use a Bearer token for PasarGuard-compatible routes. Legacy /api/v1 routes also accept HTTP Basic authentication.
Quick Start
curl -X POST https://admin.vsl247.com/api/admin/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=admin_username&password=admin_password'
curl -H 'Authorization: Bearer ACCESS_TOKEN' \
https://admin.vsl247.com/api/users
Authentication
Create a token and inspect the authenticated portal admin.
POST /api/admin/token Create a PasarGuard-style access token.
Form body
username=admin_username&password=admin_password
Response 200
{
"access_token": "...",
"token_type": "bearer"
}
GET /api/admin Return the authenticated admin.
Response 200
{
"username": "admin_username",
"is_sudo": false,
"telegram_id": null,
"discord_webhook": null,
"users_usage": 0
}
Users
Manage only the clients owned by the authenticated portal admin.
GET /api/users List owned clients with filters and pagination.
Example request
GET /api/users?offset=0&limit=10&username=client&status=active
Response 200
{
"users": [],
"total": 0
}
POST /api/user Create a user using the admin's remaining quota.
Request body
{
"username": "client_username",
"data_limit": 21474836480,
"duration_days": 30,
"status": "active",
"note": "optional"
}
Response 201
{
"username": "client_username",
"status": "active",
"used_traffic": 0,
"data_limit": 21474836480,
"subscription_url": "https://sub.vsl247.com/sub/..."
}
GET /api/user/<username> Return one owned client.
Response 200
{
"username": "client_username",
"status": "active",
"used_traffic": 1073741824,
"data_limit": 21474836480,
"expire": 1780000000,
"subscription_url": "https://sub.vsl247.com/sub/..."
}
PUT /api/user/<username> Increase quota or update expiry and status.
Request body
{
"data_limit": 32212254720,
"expire": 1780000000,
"status": "active"
}
Response 200
{
"username": "client_username",
"status": "active",
"data_limit": 32212254720,
"expire": 1780000000
}
DELETE /api/user/<username> Delete an owned client through the panel API.
Response 200
{
"detail": "User successfully deleted"
}
POST /api/user/<username>/reset Reset the client's used traffic.
Request
POST /api/user/client_username/reset
Authorization: Bearer ACCESS_TOKEN
Response 200
{
"username": "client_username",
"status": "active",
"used_traffic": 0,
"data_limit": 21474836480
}
POST /api/user/<username>/revoke_sub Revoke and regenerate the subscription link.
Request
POST /api/user/client_username/revoke_sub
Authorization: Bearer ACCESS_TOKEN
Response 200
{
"username": "client_username",
"status": "active",
"subscription_url": "https://sub.vsl247.com/sub/NEW_TOKEN"
}
Activity
Inspect subscription fetches and traffic usage.
GET /api/user/<username>/sub_update Return subscription fetch history.
Example request
GET /api/user/client_username/sub_update?offset=0&limit=10
Response 200
{
"updates": [
{
"created_at": "2026-05-29T10:25:55Z",
"user_agent": "v2rayNG/1.8.5"
}
]
}
GET /api/user/<username>/usage Return usage records for one owned client.
Example request
GET /api/user/client_username/usage?start=2026-06-01T00:00:00Z&end=2026-06-06T00:00:00Z
Response 200
{
"username": "client_username",
"usages": [
{
"node_id": 6,
"used_traffic": 268435456,
"created_at": "2026-06-05T12:00:00Z"
}
]
}
GET /api/users/usage Return usage records for all owned clients.
Example request
GET /api/users/usage?start=2026-06-01T00:00:00Z&end=2026-06-06T00:00:00Z
Response 200
{
"usages": [
{
"username": "client_username",
"node_id": 6,
"used_traffic": 268435456,
"created_at": "2026-06-05T12:00:00Z"
}
]
}
Portal-Native API
Legacy routes that use the portal's ok response wrapper.
GET /api/v1/me Return the current portal account and quota.
Response 200
{
"ok": true,
"user": {
"username": "admin_username",
"role": "admin",
"quota_bytes": 107374182400,
"remaining_bytes": 85899345920
}
}
GET /api/v1/clients Return the portal-native client list.
Example request
GET /api/v1/clients?page=1&per_page=10&search=client&live=1
Response 200
{
"ok": true,
"page": 1,
"per_page": 10,
"total": 1,
"has_next": false,
"clients": []
}
POST /api/v1/admins Create a portal admin and link a non-sudo panel admin.
Request body
{
"username": "portal_admin",
"portal_password": "portal-password",
"quota_gb": 100,
"min_client_gb": 0.5,
"subscription_host": "sub.example.com",
"marzban_admin_mode": "existing",
"marzban_username": "panel_admin",
"marzban_password": "panel-password"
}
Response 201
{
"ok": true,
"admin_id": 42
}
No matching endpoints.
Compatibility Notes
- PasarGuard-compatible routes manage only clients owned by the authenticated portal admin.
- Client creation and data-limit increases follow portal quota rules.
- Deleting a user never returns quota to the admin.
- PasarGuard-compatible responses do not use the portal-native
okwrapper. - Unsupported panel administration and system routes are not proxied.