Admin Portal API Docs

Marzban-compatible paths are available for client integrations.

Base URL

Use the same base URL style as Marzban. Both admin domains serve the same API.

https://admin.vsl247.com
https://admin2.vsl247.com

Authentication

Marzban-style Bearer token auth is supported. HTTP Basic auth still works for legacy `/api/v1` routes.

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

Compatibility Notes

  • The Marzban-compatible routes manage only the clients owned by the authenticated portal admin.
  • If an admin has a custom subscription domain, returned subscription URLs use that domain while Marzban keeps the original stored URL.
  • Marzban-compatible user creation accepts flexible expire timestamps and duration_days; the 30-day limit is only for the admin web form.
  • Client creation and data-limit increases still use portal quota rules.
  • Deleting a user does not return quota to the admin. Only superadmin charging can increase remaining quota.
  • Unsupported Marzban admin/system routes are intentionally not proxied.
POST

/api/admin/token

Returns a Marzban-style token response.

{
  "access_token": "...",
  "token_type": "bearer"
}
GET

/api/admin

Returns the authenticated admin in Marzban's admin shape.

{
  "username": "admin_username",
  "is_sudo": false,
  "telegram_id": null,
  "discord_webhook": null,
  "users_usage": 0
}
GET

/api/users

Lists owned clients. Supports offset, limit, username, and status.

{
  "users": [],
  "total": 0
}
POST

/api/user

Creates a Marzban user using the admin's remaining portal quota.

{
  "username": "client_username",
  "proxies": {"vless": {}, "shadowsocks": {}},
  "inbounds": {"vless": [], "shadowsocks": []},
  "data_limit": 21474836480,
  "expire": 1780000000,
  "data_limit_reset_strategy": "no_reset",
  "note": "optional"
}
GET

/api/user/<username>

Returns one owned client in a Marzban-like user shape.

PUT

/api/user/<username>

Supports increasing data_limit, setting expire, and setting status to active or disabled.

{
  "data_limit": 32212254720,
  "expire": 1780000000,
  "status": "active"
}
DELETE

/api/user/<username>

Deletes the owned client through the panel API and marks it deleted locally.

{
  "detail": "User successfully deleted"
}
POST

/api/user/<username>/reset

Resets the owned client's data usage through the panel API.

POST

/api/user/<username>/revoke_sub

Revokes the subscription link and returns the updated user.

GET

/api/user/<username>/sub_update

Returns subscription fetch history for one owned client. Supports offset and limit.

{
  "updates": [
    {
      "created_at": "2026-05-29T10:25:55Z",
      "user_agent": "v2rayNG/1.8.5"
    }
  ]
}
GET

/api/user/<username>/usage

Returns usage records for one owned client. Supports Marzban's start and end query parameters.

GET

/api/users/usage

Returns usage records filtered to the authenticated admin's owned clients.

GET

/api/v1/me

Portal-native route. Returns the current portal account and quota fields.

GET

/api/v1/clients

Portal-native route. Returns the older wrapped response shape with ok and clients.

POST

/api/v1/admins

Superadmin route. Set marzban_admin_mode to existing or create. Created Marzban admins are always non-sudo, and sudo Marzban admins are rejected.

{
  "username": "portal_admin",
  "portal_password": "portal-password",
  "quota_gb": 100,
  "min_client_gb": 0.5,
  "subscription_host": "test.example.com",
  "hide_branding": false,
  "marzban_admin_mode": "existing",
  "marzban_username": "marzban_admin",
  "marzban_password": "marzban-password"
}

Responses

  • Success responses include "ok": true.
  • Error responses include "ok": false and an error message.
  • Unauthenticated requests return 401.
  • Wrong role requests return 403.