VPN Backend API
REST API reference for Flutter developers integrating any of the VPN app SKUs. All endpoints are JSON.
⚡ What's new in v2.0
Every API now supports an app_name field. Send it on register, login, and usage recording so your app's data stays separate and filterable in the admin panel. See the app_name section below.
app_name Field New
Because the same backend serves multiple VPN apps, every record is now tagged with app_name. Without it records default to "default" which mixes everything together.
Your app's identifier
Agree on a short slug with the admin team and use it consistently across all calls:
Where to send it
| Endpoint | How to send | Effect |
|---|---|---|
| POST /auth/register | Request body | Tags the user record |
| POST /auth/login | Request body | Scopes login to that app's users |
| POST /vpn/usage | Inherited from user token | Tags each usage record automatically |
| GET /admin/users | Query param ?app_name= | Filters results to one app |
| GET /admin/vpn-usage | Query param ?app_name= | Filters results to one app |
Authentication
Protected endpoints require a Bearer token in the Authorization header.
Authorization: Bearer <token>
Obtain a token via POST /auth/login (users) or POST /auth/admin/login (admin).
POST /auth/register
Create a new user account. Include app_name so the user is scoped to your app.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | required | User's display name |
email | string | required | User's email address |
password | string | required | Minimum 6 characters |
app_name | string | required | Your app's identifier, e.g. "vpn_pro". Defaults to "default" if omitted. |
final response = await http.post( Uri.parse('https://vpnsbackend.oxmite.com/api/auth/register'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({ 'name': 'John Doe', 'email': 'john@example.com', 'password': 'secret123', 'app_name': 'vpn_pro', // ← your app identifier }), );
curl -X POST https://vpnsbackend.oxmite.com/api/auth/register \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "email": "john@example.com", "password": "secret123", "app_name": "vpn_pro" }'
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "64abc...",
"name": "John Doe",
"email": "john@example.com",
"status": "active",
"app_name": "vpn_pro"
},
"token": "eyJhbGci..."
}
}
POST /auth/login
Log in a user. Must send the same app_name used during registration.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | required | Registered email |
password | string | required | Account password |
app_name | string | required | Must match the app_name used at registration |
final response = await http.post( Uri.parse('https://vpnsbackend.oxmite.com/api/auth/login'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({ 'email': 'john@example.com', 'password': 'secret123', 'app_name': 'vpn_pro', // ← must match registration }), ); final token = jsonDecode(response.body)['data']['token'];
curl -X POST https://vpnsbackend.oxmite.com/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "email": "john@example.com", "password": "secret123", "app_name": "vpn_pro" }'
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": "64abc...",
"name": "John Doe",
"email": "john@example.com",
"status": "active",
"app_name": "vpn_pro"
},
"token": "eyJhbGci..."
}
}
POST /auth/admin/login
Admin login. Uses static credentials configured on the server.
| Field | Type | Required | Description |
|---|---|---|---|
email | string | required | Admin email |
password | string | required | Admin password |
curl -X POST https://vpnsbackend.oxmite.com/api/auth/admin/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@gmail.com","password":"admin@gmail.com"}'
GET /users/profile
Returns the currently authenticated user's profile.
final response = await http.get( Uri.parse('https://vpnsbackend.oxmite.com/api/users/profile'), headers: {'Authorization': 'Bearer $token'}, );
{
"success": true,
"data": {
"_id": "64abc...",
"name": "John Doe",
"email": "john@example.com",
"status": "active",
"usageLimit": 1024,
"app_name": "vpn_pro"
}
}
POST /vpn/usage
Record VPN data consumed. The app_name is automatically inherited from the logged-in user — no need to send it here.
| Field | Type | Required | Description |
|---|---|---|---|
usageMB | number | required | MB consumed in this session (≥ 0) |
app_name. You don't need to send it again.final response = await http.post( Uri.parse('https://vpnsbackend.oxmite.com/api/vpn/usage'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $token', }, body: jsonEncode({'usageMB': 25.5}), );
{
"success": true,
"message": "VPN usage recorded successfully",
"data": {
"id": "64def...",
"userId": "64abc...",
"usageMB": 25.5,
"app_name": "vpn_pro",
"totalUsage": 125.5,
"limit": 1024,
"date": "2026-06-08T10:00:00.000Z"
}
}
GET /vpn/usage
final response = await http.get( Uri.parse('https://vpnsbackend.oxmite.com/api/vpn/usage'), headers: {'Authorization': 'Bearer $token'}, );
{
"success": true,
"data": {
"userId": "64abc...",
"totalUsageMB": 125.5,
"usageLimit": 1024,
"remainingLimit": 898.5,
"usageCount": 5,
"records": [...]
}
}
GET /admin/users
Get all users. Filter by app using ?app_name= query param.
| Query Param | Required | Description |
|---|---|---|
app_name | optional | Filter to a specific app. Omit to get users from all apps. |
PATCH /admin/users/:userId/status
| Body Field | Type | Values |
|---|---|---|
status | string | "active" or "blocked" |
GET /admin/users/:userId/usage-limit
Returns current usage limit, current usage in MB, remaining, and usage percentage for the user.
POST /admin/users/:userId/usage-limit
Set a usage limit for the first time. Returns 400 if a limit already exists — use PUT instead.
| Body Field | Type | Description |
|---|---|---|
usageLimit | number | Limit in MB (≥ 0) |
PUT /admin/users/:userId/usage-limit
Update (overwrite) the usage limit for a user.
| Body Field | Type | Description |
|---|---|---|
usageLimit | number | New limit in MB (≥ 0) |
GET /admin/vpn-usage
Aggregated VPN usage for all users. Filter by app using ?app_name=.
| Query Param | Required | Description |
|---|---|---|
app_name | optional | Filter to a specific app. Omit to see all apps combined. |
{
"success": true,
"count": 3,
"data": [
{
"userId": "64abc...",
"userName": "John Doe",
"userEmail": "john@example.com",
"userStatus": "active",
"usageLimit": 1024,
"app_name": "vpn_pro",
"totalUsageMB": 125.5,
"usageCount": 5,
"lastUsage": "2026-06-08T10:00:00.000Z"
}
]
}
GET /admin/vpn-usage/:userId
Returns full usage record list for a single user including their app_name, current usage, and remaining limit.
Quick Reference
| Method | Endpoint | Auth | Notes |
|---|---|---|---|
| POST | /auth/register | — | Send app_name |
| POST | /auth/login | — | Send app_name |
| POST | /auth/admin/login | — | |
| GET | /users/profile | User | |
| POST | /vpn/usage | User | app_name auto-inherited |
| GET | /vpn/usage | User | |
| GET | /admin/users | Admin | ?app_name= filter |
| PATCH | /admin/users/:id/status | Admin | |
| GET | /admin/users/:id/usage-limit | Admin | |
| POST | /admin/users/:id/usage-limit | Admin | First-time set |
| PUT | /admin/users/:id/usage-limit | Admin | Update existing |
| GET | /admin/vpn-usage | Admin | ?app_name= filter |
| GET | /admin/vpn-usage/:userId | Admin |
VPN Backend API v2.0 · Generated 2026