No matching endpoints
Nothing here matches
Stuur de X-App-Secret-header van je app en POST JSON naar /api/auth/* om sleutels te valideren en sessies te beheren. Genereer sleutels via /api/admin/* met een Bearer-token. Antwoorden zijn altijd { "success": true|false, … }.
Inleiding
De PWF Auth-API is opgebouwd rond REST. Alle verzoeken en antwoorden zijn JSON over HTTPS. Er zijn drie families van endpoints:
- Client-API (
/api/auth/*,/api/update/*) — aangeroepen vanuit je uitgeleverde applicatie met het app-secret. - Admin-API (
/api/admin/*) — sleutel- & app-beheer, geauthenticeerd met een Bearer-token. - Klant-/reseller-API (
/api/customer/*,/api/reseller/*) — selfserviceportalen.
Alle paden hieronder zijn relatief ten opzichte van die basis-URL. Elk endpoint vereist HTTPS; gewone HTTP-verzoeken worden omgeleid.
Prefer machines? The whole surface is described in openapi.json (OpenAPI 3.1) — import it into Postman, Insomnia, or a code generator.
API and platform changes are announced in the changelog — breaking changes are always flagged there first.
Authenticatie
Client-endpoints — App-secret
Stuur het secret van je app in de X-App-Secret-header. Je vindt het in Dashboard → je app. Het secret bepaalt bij welke applicatie een verzoek hoort.
curl https://pwfauth.com/api/auth/check-key.php \
-H "X-App-Secret: 9f02532d9c60… # 64-char hex, from your dashboard" \
-H "Content-Type: application/json" \
-d '{"license_key":"XXXXX-XXXXX-XXXXX-XXXXX"}'
Admin-endpoints — Bearer-token
Authenticeer bij /api/admin/login.php om een JWT te krijgen en stuur die bij elke admin-aanroep als Authorization: Bearer <token>.
TOKEN=$(curl -s https://pwfauth.com/api/admin/login.php \
-d '{"username":"admin","password":"…"}' | jq -r .token)
curl https://pwfauth.com/api/admin/keys.php \
-H "Authorization: Bearer $TOKEN"
De versleutelde envelop
SDK-endpoints wisselen een AES-256-CBC + HMAC-SHA256-envelop uit in plaats van platte JSON. Het wire-formaat is {"p": base64(IV || ciphertext), "t": unix_timestamp, "s": hmac_sha256_hex(p + t)} — de encryptie- en MAC-sleutels worden beide afgeleid van je app-secret, dus extra sleuteluitwisseling is niet nodig.
{
"p": "aXYxNmJ5dGVzY2lwaGVydGV4dA…", // base64( IV || AES-256-CBC ciphertext )
"t": 1785671000, // unix timestamp (±300s accepted)
"s": "b7fd09…" // hmac_sha256_hex( p + t, mac_key )
}
Endpoints gemarkeerd met App-secret + versleutelde envelop vereisen hem in het verzoek en antwoorden versleuteld. check-key.php detecteert automatisch: stuur platte JSON en je krijgt platte JSON terug (daarom werken de curl-voorbeelden op deze pagina); stuur een envelop en het antwoord komt versleuteld.
Enveloppen ouder dan ±300 seconden worden geweigerd, dus houd de klok van de client redelijk nauwkeurig. Je hoeft dit nooit zelf te bouwen: de open-source voorbeeldclients (VB.NET, C#, Python) bevatten een kant-en-klare CryptoEnvelope-implementatie.
How the envelope is built
Both directions use the same recipe. Two keys are derived from your app secret, so every app gets distinct encryption and signing keys:
enc_key = SHA256("enc:" + app_secret) # 32 bytes
mac_key = SHA256("mac:" + app_secret) # 32 bytes
# client → server (and server → client — same recipe)
iv = random_bytes(16)
ct = AES-256-CBC(enc_key, iv, json_body) # PKCS#7 padding
p = base64(iv || ct)
t = unix_time() # ±300 s accepted
s = hex(HMAC-SHA256(p + str(t), mac_key))
send { "p": p, "t": t, "s": s }
# receiving: verify s FIRST (constant-time), check |now - t| ≤ 300,
# then base64-decode p, split off the 16-byte IV, decrypt the rest.
Which endpoints require it
Each endpoint card carries a colour-coded auth pill; this table is the same information at a glance:
| Auth model | Endpoints |
|---|---|
| Openbaar | app/changelog · app/pricing · admin/login |
| App-secret · plain of envelop | auth/check-key |
| App-secret | auth/trial · auth/request-hwid-reset · auth/account-register · auth/account-login · auth/change-password · update/validate · update/download |
| App-secret + versleutelde envelop | auth/login · auth/heartbeat · auth/logout · app/text · app/slides · app/info · app/social-click · update/check |
| Bearer | admin/* |
| Fulfillment-secret | app/fulfill |
Antwoorden & fouten
Elk antwoord bevat een booleaanse success. Fouten voegen een leesbare message toe en een stabiele, machineleesbare error_code:
{
"success": false,
"message": "This license key has been banned.",
"error_code": "BANNED"
}
| error_code | Betekenis |
|---|---|
MISSING_FIELDS | Een vereist body-veld ontbreekt. |
INVALID_KEY | De licentiesleutel bestaat niet voor deze app. |
INVALID_CREDENTIALS | Gebruikersnaam/wachtwoord geweigerd (gebruikersaccounts + admin-login). |
HWID_MISMATCH | De sleutel is aan een ander apparaat gebonden. |
EXPIRED | De licentie is verlopen. |
BANNED / PAUSED | De sleutel is geblokkeerd of gepauzeerd door de eigenaar. |
MAINTENANCE | De app staat in onderhoudsmodus. |
SESSION_EXPIRED / SESSION_MISMATCH | De heartbeat-sessie is ongeldig. |
TOO_MANY_ATTEMPTS | Login brute-force lockout — the account is locked temporarily; retry_after in the response says for how many seconds. |
TRIAL_DISABLED / TRIAL_USED / TRIAL_LIMIT | Proefversie geweigerd — uitgeschakeld voor deze app, al gebruikt op dit apparaat, of de IP-limiet is bereikt. |
HTTP-statuscodes
| error_code | Betekenis |
|---|---|
200 | Succes — de JSON-body bevat het resultaat. |
400 | Validatie mislukt — ontbrekende of ongeldige velden (zie error_code). |
401 | X-App-Secret of Bearer-token ontbreekt of is ongeldig. |
403 | Geauthenticeerd maar niet toegestaan (verkeerde app, ingetrokken token …). |
404 | Resource niet gevonden. |
405 | Verkeerde HTTP-methode voor dit endpoint. |
429 | Rate limited — wait for the Retry-After header before retrying. |
500 | Serverfout — bewust een generieke melding; probeer het later opnieuw. |
Rate-limits & fair use
Er is geen algemeen verzoekquotum, maar een paar misbruikbeveiligingen zijn actief:
- Admin-login is beschermd tegen brute force — herhaalde mislukkingen vergrendelen het account tijdelijk.
- Proefversies zijn begrensd per apparaat (HWID) en per IP; overschrijding geeft
TRIAL_LIMIT. - Secret-regeneratie is per app rate-limited om onbedoelde rotatielussen te stoppen.
- Houd heartbeats op het interval dat de login-respons je geeft (standaard 30 s) — sneller vuren voegt niets toe.
Snelstart
De minimale integratie: valideer een sleutel bij het starten van je app en houd de sessie daarna met een heartbeat in leven.
# Validate a key from the terminal (plain JSON works here)
curl -X POST https://pwfauth.com/api/auth/check-key.php \
-H "X-App-Secret: $APP_SECRET" \
-d '{"license_key":"XXXXX-XXXXX-XXXXX-XXXXX"}'
# → { "success": true, "valid": true, "key": { "status": "active", … } }
Let op: de volledige sessieflow (login → heartbeat → logout) gebruikt de versleutelde envelop en is dus niet handmatig met curl te testen. Sluit hem in minuten aan via de Quick Start in het panel (genereert werkende snippets in 9 talen met je echte gegevens) of de open-source voorbeeldclients.
The same flow with an official SDK
Login, heartbeat and the server-side kill switch in a few lines — the SDK handles the encrypted envelope for you:
// dotnet add package PWFAuth
using PWFAuth;
var client = new PwfClient(APP_SECRET);
client.SessionEnded += (s, e) => // ban / pause / expiry / revoke / offline
{
Console.WriteLine($"{e.ErrorCode}: {e.Message}");
Environment.Exit(0);
};
var login = await client.LoginAsync("XXXXX-XXXXX-XXXXX-XXXXX");
if (!login.Success) { Console.WriteLine(login.Message); return; }
client.StartHeartbeat(); // keeps the session alive AND enforces the kill switch
' dotnet add package PWFAuth
Dim client As New PwfClient(APP_SECRET)
AddHandler client.SessionEnded, Sub(s, e) ' ban / pause / expiry / revoke / offline
MessageBox.Show(e.Message)
Application.Exit()
End Sub
Dim login = Await client.LoginAsync("XXXXX-XXXXX-XXXXX-XXXXX")
If login.Success Then client.StartHeartbeat()
# pip install pwfauth
import sys
from pwfauth import PwfClient
client = PwfClient(APP_SECRET)
client.on_session_ended = lambda code, msg: sys.exit(msg) # kill switch
login = client.login("XXXXX-XXXXX-XXXXX-XXXXX")
if not login.success:
sys.exit(login.message)
client.start_heartbeat() # keeps the session alive AND enforces the kill switch
// npm install pwfauth
import { PwfClient } from 'pwfauth';
const client = new PwfClient(process.env.PWFAUTH_SECRET);
client.on('sessionEnded', ({ errorCode, message }) => { // kill switch
console.error(`${errorCode}: ${message}`);
process.exit(1);
});
const login = await client.login('XXXXX-XXXXX-XXXXX-XXXXX');
if (!login.success) { console.error(login.message); process.exit(1); }
client.startHeartbeat(); // keeps the session alive AND enforces the kill switch
Licenties & sessies
Activeer een sleutel bij het eerste gebruik, bind hem aan de HWID van het apparaat en open een sessie. Hervalideert en start een nieuwe sessie bij volgende aanmeldingen. Dwingt max_devices af door de oudste sessie te beëindigen.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
license_key | verplicht | De te activeren / te valideren licentiesleutel. |
hwid | verplicht | Stabiele hardware-vingerafdruk van het apparaat. |
{
"success": true,
"session_id": "8f2c…",
"user": {
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX",
"key_type": "days", "duration": 30,
"expires_at": "2026-09-01T12:00:00Z",
"days_remaining": 30, "status": "active"
},
"features": { "pro_tier": true },
"heartbeat_interval": 30
}
Houdt een sessie actief. Roep hem elke heartbeat_interval seconden aan (geretourneerd door login). Stop je ermee, dan wordt de sessie serverzijdig opgeruimd.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
session_id | verplicht | Sessie geretourneerd door login. |
license_key | optioneel | Indien meegestuurd, moet de sessie bij deze sleutel horen. |
{ "success": true, "message": "Heartbeat received" }
// the moment the key is banned / paused / expired / reset, the SAME call answers:
{ "success": false, "error_code": "BANNED",
"message": "This license key has been banned." } // session is dropped — log the user out
Sluit een sessie onmiddellijk (bijv. bij afsluiten van de app). Body: session_id verplicht, license_key optioneel.
Lichte statuscontrole — geen sessie, geen HWID-binding. Handig voor een controle „is deze sleutel nog geldig?“.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
license_key | verplicht | De te inspecteren sleutel. |
curl -X POST https://pwfauth.com/api/auth/check-key.php \
-H "X-App-Secret: $APP_SECRET" \
-d '{"license_key":"XXXXX-XXXXX-XXXXX-XXXXX"}'
var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-App-Secret", APP_SECRET);
var res = await http.PostAsync("https://pwfauth.com/api/auth/check-key.php",
new StringContent("{\"license_key\":\"XXXXX-XXXXX-XXXXX-XXXXX\"}"));
import urllib.request, json
req = urllib.request.Request("https://pwfauth.com/api/auth/check-key.php",
data=json.dumps({"license_key": "XXXXX-XXXXX-XXXXX-XXXXX"}).encode(),
headers={"X-App-Secret": APP_SECRET})
print(json.load(urllib.request.urlopen(req)))
const res = await fetch('https://pwfauth.com/api/auth/check-key.php', {
method: 'POST',
headers: { 'X-App-Secret': process.env.APP_SECRET },
body: JSON.stringify({ license_key: 'XXXXX-XXXXX-XXXXX-XXXXX' })
});
console.log(await res.json());
$ch = curl_init('https://pwfauth.com/api/auth/check-key.php');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-App-Secret: ' . $APP_SECRET],
CURLOPT_POSTFIELDS => '{"license_key":"XXXXX-XXXXX-XXXXX-XXXXX"}']);
$res = json_decode(curl_exec($ch), true);
{
"success": true, "valid": true,
"key": {
"status": "active", "key_type": "days", "duration": 30,
"activated_at": "2026-08-02T12:00:00Z",
"expires_at": "2026-09-01T12:00:00Z",
"days_remaining": 30, "max_devices": 1
}
}
Lichte licentievalidatie zonder HWID-binding of sessie — ideaal als pre-flightcheck vóór de volledige login. Platte JSON erin, platte JSON eruit.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
license_key | verplicht | De te inspecteren sleutel. |
Dien een HWID-resetverzoek in vanuit je in-app-dialoog wanneer een gebruiker van machine wisselt. De app-eigenaar keurt het goed in het dashboard.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
license_key or username | verplicht | Bepaalt wiens binding wordt gereset. |
reason | optioneel | Notitie die aan de eigenaar wordt getoond. |
Gratis proefversies
Geef een tijdelijke proefsleutel uit, gebonden aan het verzoekende apparaat. Eén proef per HWID per app. De proefduur stelt de app-eigenaar in.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
hwid | verplicht | Apparaat-vingerafdruk die de proef aanvraagt. |
{
"success": true, "message": "Trial activated! You have 3 days.",
"trial_key": "TRIAL-1A2B3-C4D5E-F6A7B",
"session_id": "8f2c…",
"expires_at": "2026-08-23T12:00:00Z", "days_remaining": 3,
"user": { "key_type": "days", "status": "active", … },
"app": { "name": "…", "version": "…" }
}
Gebruikersaccounts
Liever aanmelden met gebruikersnaam/wachtwoord dan met losse sleutels? PWF Auth biedt een volledig accountmodel met bcrypt-hashing en HWID-binding.
Maak een eindgebruikersaccount aan. Body: username, password verplicht, email optioneel.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
username | verplicht | Gewenste gebruikersnaam (uniek per app). |
password | verplicht | Wachtwoord (server-side gehasht opgeslagen). |
email | optioneel | Contact-e-mailadres voor het account. |
Authenticeer en bind een apparaat. Body: username, password, hwid verplicht. Geeft dezelfde sessievorm terug als login.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
username | verplicht | Gebruikersnaam van het account. |
password | verplicht | Wachtwoord van het account. |
hwid | verplicht | Apparaat-fingerprint om de sessie aan te binden. |
Wijzig het wachtwoord van een gebruiker. Body: username, current_password, new_password verplicht.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
username | verplicht | Gebruikersnaam van het account. |
current_password | verplicht | Huidig wachtwoord (gecontroleerd vóór de wijziging). |
new_password | verplicht | Nieuw wachtwoord. |
App-content & remote-beheer
Via deze endpoints haalt je uitgeleverde app content op die je live in het panel bewerkt — teksten, slides, prijzen, changelog — zonder een update uit te brengen.
Remote tekst(en) ophalen. Met ?name=… komt één item terug; zonder parameter alle teksten van de app. Sleutel-overrides winnen van app-defaults. De licentiesleutel reist mee in Authorization: Bearer
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
?name | optioneel | Op te halen tekstsleutel (weglaten voor alles). |
Geeft de actieve aankondigingsslides van de app terug. Stuur de envelop-body {"action":"get_slides"}; het antwoord is versleuteld.
App-metadata + sociale links (naam, branding, URL's). Antwoord in envelop.
Verhoogt de klikteller van een sociale link (voor de engagementstatistieken in het panel).
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
link_id | verplicht | Numeriek id van de sociale link. |
Publieke changelog-feed zonder auth voor één app — render overal een "Wat is nieuw"-widget. Alleen gepubliceerde items.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
?app_id | verplicht | De app waarvan de changelog gelezen wordt. |
?limit | optioneel | 1–50, standaard 20. |
?since | optioneel | ISO-datum — alleen items gepubliceerd op/na deze datum. |
?category | optioneel | Filter: new / improved / fixed / removed / security / deprecated. |
Publieke prijsinterface: abonnementsniveaus en legacy-plannen van een app; POST maakt een bestelling aan; ?action=check leest het actieve abonnement van een gebruiker.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
?app_id | verplicht | De app waarvan de prijzen gelezen worden. |
?type | optioneel | levels of plans (weglaten voor beide). |
Server-naar-server orderafhandeling voor geautomatiseerde betaalgateways — een geverifieerde IPN voltooit de bestelling en start sleutelgeneratie + levering. Geauthenticeerd met het gedeelde fulfillment-secret uit je panelinstellingen, nooit met een gebruikerssessie.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
order_id | verplicht | De af te handelen bestelling (ORD-…). |
secret | verplicht | Je order_fulfill_secret. |
payment_ref | optioneel | Optionele betaalreferentie van de gateway. |
OTA-updates
Vraag of er een nieuwere build beschikbaar is voor de aanroeper — met inachtneming van kanaal, OS-/arch-filters, minimumversie-gates en gefaseerde uitrol (dezelfde aanroeper komt stabiel in dezelfde slice).
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
v | verplicht | Huidige versie van de aanroeper (semver). |
channel | optioneel | stable (standaard), beta of alpha. |
os / arch | optioneel | windows·macos·linux / x64·x86·arm64. |
hwid / license_key | optioneel | Wordt gebruikt voor stabiele uitrol-bucketing. |
{
"success": true, "update_available": true,
"update": {
"version": "1.4.0", "channel": "stable",
"is_mandatory": false, "file_size": 5242880,
"sha256": "…", "changelog": "…",
"download_url": "api/update/download.php?v=1.4.0"
}
}
Stream het binaire bestand voor een bepaalde versie. Gebruik de download_url die check.php teruggeeft en verifieer de sha256 na het downloaden.
Webhooks
Turn events into HTTP calls to your server: key activations, bans, expiries, orders, new updates and more. Configure destinations per app (or for all apps) in the panel under Application → Webhooks, pick the events you care about, and PWF Auth POSTs a signed JSON body to your URL. Delivery is queue-based — expect it within a minute or two of the event, not in the same instant.
Delivery payload
{
"event": "key.activated",
"timestamp": "2026-08-20T14:07:02Z",
"data": {
"app_id": "01af6643-…",
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX",
"hwid": "A1B2C3…"
}
}
Delivery headers
| Header | Beschrijving |
|---|---|
X-Webhook-Id | Unique delivery id (whd_…). Stays the same across retries of one event — use it to deduplicate. |
X-Webhook-Timestamp | Unix timestamp of the delivery attempt. |
X-Webhook-Attempt | 1-based attempt counter. |
X-Webhook-Signature | Legacy signature: hex(HMAC-SHA256(body, secret)). |
X-Webhook-Signature-V2 | Preferred signature: t=<ts>,v1=hex(HMAC-SHA256(ts + "." + body, secret)) — the timestamp inside the MAC makes replays detectable. |
Verifying the signature
Always verify before trusting a delivery: compute the V2 MAC over timestamp + "." + raw body with your endpoint secret, compare in constant time, and reject stale timestamps (±5 minutes is plenty). Answer 2xx fast — heavy work belongs in your own queue.
// X-Webhook-Signature-V2: t=<ts>,v1=<hex>
[$t, $v1] = explode(',', $_SERVER['HTTP_X_WEBHOOK_SIGNATURE_V2'] ?? ',');
$t = substr($t, 2); $v1 = substr($v1, 3);
$raw = file_get_contents('php://input');
$ok = hash_equals(hash_hmac('sha256', $t . '.' . $raw, $secret), $v1)
&& abs(time() - (int)$t) < 300;
if (!$ok) { http_response_code(400); exit; }
http_response_code(200); // answer fast — queue heavy work
// X-Webhook-Signature-V2: t=<ts>,v1=<hex>
const [t, v1] = req.headers['x-webhook-signature-v2']
.split(',').map(kv => kv.split('=')[1]);
const mac = crypto.createHmac('sha256', secret)
.update(`${t}.${rawBody}`).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(v1))
&& Math.abs(Date.now() / 1000 - Number(t)) < 300;
res.sendStatus(ok ? 200 : 400); // answer fast — queue heavy work
# X-Webhook-Signature-V2: t=<ts>,v1=<hex>
import hmac, time
t, v1 = (kv.split("=", 1)[1]
for kv in request.headers["X-Webhook-Signature-V2"].split(","))
mac = hmac.new(secret, f"{t}.{raw_body}".encode(), "sha256").hexdigest()
ok = hmac.compare_digest(mac, v1) and abs(time.time() - int(t)) < 300
return ("", 200) if ok else ("", 400) # answer fast — queue heavy work
Retries & failure policy
- A delivery counts as successful on any
2xx/3xxanswered within 5 seconds. - Failures retry up to 5 attempts with widening gaps: 1 m → 5 m → 30 m → 2 h → 6 h.
X-Webhook-Idis minted once per event and reused on every retry — idempotency is oneseen?lookup away.- A destination that fails 20 times in a row is paused automatically; re-enable it from the panel (a
testevent button is right there).
Events
Subscribe to specific events or leave the filter empty to receive them all. event in the body tells you which one fired:
| Event | Fires when |
|---|---|
key.created | Keys are generated (panel or admin API). |
key.activated | A key's first successful login binds it to a device. |
key.banned / key.unbanned | A key is banned / unbanned. |
key.deleted | A key is deleted. |
key.rotated | A key string is rotated (the old string stops working). |
key.suspected_leak | Leak detection flags a key as suspected shared/leaked. |
key_expiring | A key approaches expiry (scheduled sweep). |
key_expired | A key expires (scheduled sweep). |
trial.created | A trial key is issued to a new device. |
hwid_reset.requested | A client requests a device (HWID) reset. |
new_order | A purchase order is created. |
order.approved | An order is approved and fulfilled. |
subscription.* | Subscription lifecycle: created / renewed / cancelled / renewal order created. |
update.published | A new application version is published. |
changelog.published | A changelog entry goes live. |
app.revoked | An application is revoked / disabled. |
suspicious_activity | The suspicious-activity heuristic fires. |
test | Manual test delivery from the panel. |
Admin-API
Serverzijdige endpoints voor het beheren van apps en sleutels. Alle vereisen een Authorization: Bearer-token van het login-endpoint hieronder.
Wil je je wachtwoord niet in een script bewaren? Maak in het panel onder Profiel → API Tokens een Personal Access Token aan en gebruik het als Bearer-waarde (pwf_…). Het verloopt nooit totdat jij het intrekt, werkt op elk /api/admin/*-endpoint en is bewust uitgesloten van credential-beheer (wachtwoord, e-mail, 2FA, extra tokens).
Wissel inloggegevens in voor een JWT. Als 2FA is ingeschakeld, wordt requires_2fa + een step1_token teruggegeven, af te ronden via /api/admin/totp.php.
| Body-veld | Verplicht? | Beschrijving |
|---|---|---|
username | verplicht | Admin-gebruikersnaam. |
password | verplicht | Admin-wachtwoord. |
Genereer licentiesleutels in bulk. Hetzelfde endpoint ondersteunt ook GET (lijst), PUT (bewerken), DELETE en actie-queries zoals ?action=ban|pause|extend|reset-hwid en ?action=export.
curl -X POST https://pwfauth.com/api/admin/keys.php \
-H "Authorization: Bearer $TOKEN" \
-d '{"app_id":"01af6643-cf3a-4280-b9ce-cb5fa8ae987c",
"count":100,"key_type":"days","duration_value":30}'
Het admin-oppervlak dekt ook apps, sessions, updates, feature-flags, webhooks, analytics, audit, resellers en meer — elk onder /api/admin/ met dezelfde Bearer-auth. Log in op het dashboard om ze te verkennen.
SDK's
De REST-API werkt vanuit alles wat een HTTP-verzoek kan sturen. Officiële single-file SDK's zijn beschikbaar voor VB.NET / C#, met eersteklas voorbeelden voor Python en PHP. Al het andere — Node, Go, Rust, Java, Swift — praat met dezelfde JSON-endpoints hierboven.
- Open-source voorbeeldclients (VB.NET · C# · Python) — volledige login/heartbeat/envelop-flows, klaar om te kopiëren
- Quick Start in het panel — 5 begeleide stappen genereren werkende snippets in 9 talen met je echte gegevens
- OpenAPI 3.1 spec (
openapi.json) — one-click import into Postman / Insomnia, or feed it to your code generator
Klaar om te integreren?
Maak een gratis account aan, registreer een app en kopieer je X-App-Secret uit het dashboard.