A complete self-hosted platform for license key management, user authentication, session control, OTA updates, and app distribution — all in one lightweight PHP server.
Built-in systems for licensing, authentication, real-time sessions, OTA updates, and a complete admin panel.
Generate, activate, and manage license keys with support for time-based expiry (days, weeks, months), lifetime keys, HWID binding, multi-device limits, pause/resume, and batch generation.
Full user account system with username/password authentication, registration, expiry management, HWID binding, and profile management — perfect for SaaS-style apps.
Track active sessions with heartbeat monitoring, auto-cleanup of dead sessions, device-level control, and forced logout capabilities.
Distribute updates to your apps with version checking, file manifests (add/update/delete actions), mandatory update flags, ZIP download, and changelog management.
Superadmin manages all apps; Developers can create and manage multiple applications. Developer self-registration with multi-app support. Full SPA admin panel included.
JWT authentication, bcrypt password hashing, IP-based rate limiting, app secret validation, CORS control, and comprehensive audit logging for every action.
Whether you're building desktop software, mobile apps, or SaaS platforms.
License key activation with HWID binding and OTA updates for Windows/macOS/Linux apps.
Account-based logins with device limits, session control, and push-style update checks.
User account management with plan types, expiry dates, and real-time session monitoring.
Quick license validation for CLI tools, automation bots, and scripts with minimal overhead.
All endpoints accept/return JSON with X-App-Secret header authentication for client endpoints.
| Header | Value |
|---|---|
| X-App-Secret | Your app's secret key |
{
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX",
"hwid": "unique-device-id"
}
{
"success": true,
"session_id": "uuid",
"license": {
"key_type": "months",
"expires_at": "2026-04-18T00:00:00Z",
"days_remaining": 30,
"max_devices": 1
},
"app": {
"app_name": "My App",
"current_version": "1.0.0",
"login_message": "Welcome!"
}
}
{
"username": "user1",
"password": "pass123",
"hwid": "device-id"
}
{
"success": true,
"session_id": "uuid",
"user": {
"username": "user1",
"key_type": "months",
"expires_at": "2026-04-18T00:00:00Z",
"days_remaining": 30
}
}
{
"session_id": "your-session-id"
}
{
"success": true,
"message": "Heartbeat received"
}
{
"session_id": "your-session-id"
}
{
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX"
}
{
"success": true,
"valid": true,
"license": {
"key_type": "months",
"status": "active",
"expires_at": "2026-04-18T00:00:00Z",
"days_remaining": 30
}
}
{
"current_version": "1.0.0"
}
{
"success": true,
"update_available": true,
"update": {
"version": "2.0.0",
"changelog": "New features...",
"is_mandatory": false,
"file_size": 5242880,
"download_url": "api/update/download.php?v=2.0.0",
"files": [
{ "file_name": "app.exe", "file_size": 5242880, "action": "update" },
{ "file_name": "module.dll", "file_size": 2048, "action": "add" },
{ "file_name": "old.dll", "file_size": 0, "action": "delete" }
]
}
}
Returns binary ZIP file with Content-Type: application/zip headers. The download is logged in the audit trail.
{
"success": true,
"slides": [
{ "image_url": "...", "line1": "...", "line2": "...", "sort_order": 1 }
]
}
{
"success": true,
"status": "online",
"maintenance_mode": false,
"current_version": "1.0.0"
}
{
"username": "my_company",
"password": "securepass",
"email": "[email protected]"
}
{
"success": true,
"token": "eyJhbGciOi...",
"admin": { "id": 5, "username": "my_company", "role": "app_admin", "app_id": null },
"message": "Registration successful. Create your first app to get started."
}
{
"username": "admin",
"password": "admin123"
}
All admin resources support GET (list/detail), POST (create), PUT (update), DELETE (remove).
Requires Authorization: Bearer <JWT> header. App admins are automatically scoped to their own app.
| Endpoint | Description |
|---|---|
| dashboard.php | Stats overview (keys, sessions, accounts, apps) |
| keys.php | License key management + batch generate |
| accounts.php | User account CRUD + actions (ban, pause, reset) |
| apps.php | Application management (superadmin) |
| slides.php | In-app slide/banner management |
| updates.php | OTA update management + ZIP upload |
| sessions.php | Session monitoring + force disconnect |
| logs.php | Audit log viewer with filters |
| admins.php | App admin management (superadmin) |
From zero to a fully working license server — no external dependencies required.
Copy the pwf-license-server folder to your PHP hosting (Apache/Nginx + PHP 8.0+). No Composer, no npm, no database setup — SQLite auto-initializes on first request.
# Just copy the files — that's it!
/your-web-root/
└── pwf-license-server/
├── admin/ # Admin panel SPA
├── api/ # REST API endpoints
├── includes/ # Core PHP files
└── index.php # This page
Visit the Admin Panel and click "Register as Developer". This creates your developer account. After logging in, go to "My Apps" to create your first application and get your App Secret.
# Or register via API:
curl -X POST http://your-domain/api/admin/register.php \
-H "Content-Type: application/json" \
-d '{
"username": "my_company",
"password": "secure_password",
"email": "[email protected]"
}'
From the admin panel, go to License Keys → "Generate Keys". Choose key type (days/weeks/months/lifetime), duration, and number of keys. Or create User Accounts for account-based auth.
# Generate keys via API:
curl -X POST your-domain/api/admin/keys.php \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"app_id": "your-app-uuid",
"key_type": "months",
"duration_value": 1,
"count": 10
}'
Use simple HTTP requests from any language. Here's how a client app authenticates:
# Login with a license key:
curl -X POST your-domain/api/auth/login.php \
-H "X-App-Secret: YOUR_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX",
"hwid": "unique-device-id"
}'
# Check for updates:
curl -X POST your-domain/api/update/check.php \
-H "X-App-Secret: YOUR_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{ "current_version": "1.0.0" }'
No heavy frameworks. No complicated setup. Just PHP and SQLite.
Register as a developer and start protecting your apps in minutes.