Administration Workflows¶
Privileged operations for running a V2Hub instance: provisioning users and providers, managing IP bans and whitelists, and pulling usage statistics. These require the v2hub-admin package (or v2hub-cli with its optional admin extra) and an admin secret_key — see Authentication Workflows → Admin secret key.
from v2hub_admin import AsyncAdminClient
async with AsyncAdminClient(base_url="https://api.example.com", secret_key="admin-secret") as admin:
...
The CLI equivalent is v2hub admin ... — see V2Hub CLI → Admin Commands for every command this guide's Python examples map to.
User Management¶
Provision, inspect, and manage end-user accounts:
user = await admin.create_user(user_id=12345)
print(user.api_token) # hand this to the user/their application — see Authentication Workflows
user = await admin.get_user(12345)
print(user.is_active)
user = await admin.set_user_status(12345, is_active=False) # suspend
result = await admin.refresh_token(user_id=12345)
print(result.new_api_token) # rotate a compromised or expiring token
await admin.delete_user(12345) # irreversible
A common pattern: create the user, immediately store user.api_token in your own system (it's shown once, at creation, like most API tokens), and hand it to whatever application or bot acts on the user's behalf.
Provider Management¶
Providers are external services (bots, resellers, integrations) that manage subscriptions on behalf of end-users via as_provider_for_user_id= — see Provider Workflows for that side of the relationship. This section is about the provider account lifecycle itself:
provider = await admin.create_provider(
owner_hash="a1b2c3d4e5f6...", # the user_hash of the account that owns this provider
provider_name="my-bot",
provider_url="https://t.me/examplebot",
)
print(provider.provider_hash, provider.api_token)
providers = await admin.get_providers()
for name, provider_hash in providers.provider_hashes.items():
print(name, provider_hash)
provider = await admin.get_provider_by_name("my-bot")
provider = await admin.get_provider_by_owner_id(owner_id=12345)
provider = await admin.set_provider_status(provider.provider_hash, is_active=False)
result = await admin.refresh_provider_token(provider.provider_hash)
print(result.new_api_token)
await admin.delete_provider(provider.provider_hash) # cascades to provider-owned data
owner_hash ties a provider account back to the user account that "owns" it (typically the operator running the bot/service) — obtain it from get_user/create_user's response for that owning account before calling create_provider.
Provider Authorization Management¶
The admin-side view of the provider↔user authorization handshake described from the provider's perspective in Provider Workflows → Connection lifecycle:
# Process an incoming request (the provider issued an HMAC-signed invite to the user)
auth = await admin.process_provider_authorization(
user_id=12345,
provider_name="my-bot",
hmac="a1b2c3d4e5f6...",
)
print(auth.status) # "pending"
# Approve or reject it
auth = await admin.approve_provider_authorization(user_id=12345, provider_name="my-bot")
# or
await admin.reject_provider_authorization(user_id=12345, provider_name="my-bot")
# Check status at any time
auth = await admin.get_provider_authorization("my-bot", user_id=12345)
approve_provider_authorization and reject_provider_authorization only operate on PENDING authorizations and raise ConflictError otherwise — including when the target user has already reached the server's provider-per-user limit. reject_provider_authorization's result depends on history: the authorization is deleted outright if the user never had subscriptions from that provider, or kept as REVOKED if they did (so existing subscriptions remain traceable).
Getting Users' Provider Connections (read side)¶
To inspect a user's connections from the admin side without going through the user's own token:
connections = await admin.get_user_providers(user_id=12345)
for conn in connections.connections:
print(conn.provider_name, conn.status)
connection = await admin.get_user_provider(user_id=12345, provider_name="my-bot")
IP Ban Management¶
ban = await admin.ban_ip("192.168.1.100", duration_seconds=3600) # 1 hour
print(ban.banned_until, ban.remaining_seconds)
ban = await admin.ban_ip("203.0.113.5") # server default duration
status = await admin.get_ban_status("192.168.1.100")
if status.is_banned:
print(f"Banned until {status.banned_until}")
result = await admin.unban_ip("192.168.1.100")
print(result.was_banned) # False if it wasn't actually banned — safe to call unconditionally
bans = await admin.get_ban_list()
print(f"{bans.total} active bans")
for ban in bans.entries:
print(ban.ip_address, ban.banned_until)
Whitelist Management¶
Whitelisting takes precedence over bans for the listed range — use it for known-good infrastructure (your own servers, office networks) that should never be affected by rate limiting or the ban system:
result = await admin.add_to_whitelist("10.0.0.0/24", description="Office network")
print(result.message)
whitelist = await admin.list_whitelist()
for entry in whitelist.entries:
print(entry.ip_address, entry.description, entry.added_at)
result = await admin.remove_from_whitelist("10.0.0.0/24")
print(result.was_whitelisted)
Usage Statistics¶
from datetime import datetime, timedelta
# Predefined period
stats = await admin.get_stats(period="week") # "day" | "week" | "month"
# Explicit range
stats = await admin.get_stats(
start_date=datetime.now() - timedelta(days=30),
end_date=datetime.now(),
)
# Omit everything for the API's default range
stats = await admin.get_stats()
Useful for a periodic reporting job, an internal dashboard, or alerting on unusual traffic — see Common Integration Patterns for a scheduled-job shape you can adapt.
Error handling for admin operations¶
Admin errors share v2hub's exception hierarchy, so the same patterns from Error Handling Patterns apply directly:
from v2hub import VPNAPIError, AuthenticationError, AuthorizationError, NotFoundError
try:
await admin.delete_user(12345)
except AuthenticationError:
# invalid HMAC signature — almost always a wrong or misconfigured secret_key
...
except NotFoundError:
# user_id doesn't exist — already deleted, or never existed
...
except AuthorizationError:
# signature is valid but this operation isn't permitted
...
except VPNAPIError as e:
print(e, e.recovery_hint)
Where to go next¶
- Authentication Workflows → Admin secret key for how the
secret_keyitself is handled and secured. - Provider Workflows for the non-admin side of provider authorization.
- V2Hub CLI → Admin Commands for every one of these operations from the terminal, including the graceful fallback behavior when
v2hub-adminisn't installed.