Нет подходящих эндпоинтов
Ничего не совпадает с
Отправляйте заголовок X-App-Secret вашего приложения и POST-ите JSON на /api/auth/*, чтобы проверять ключи и вести сессии. Генерируйте ключи через /api/admin/* с Bearer-токеном. Ответы всегда имеют вид { "success": true|false, … }.
Введение
API PWF Auth построен вокруг REST. Все запросы и ответы — JSON по HTTPS. Есть три семейства эндпоинтов:
- Client API (
/api/auth/*,/api/update/*) — вызывается из вашего готового приложения с секретом приложения. - Admin API (
/api/admin/*) — управление ключами и приложениями, аутентификация Bearer-токеном. - Customer / reseller API (
/api/customer/*,/api/reseller/*) — порталы самообслуживания.
Все пути ниже указаны относительно базового URL. Каждый эндпоинт требует HTTPS; запросы по обычному HTTP перенаправляются.
Предпочитаете машины? Вся поверхность описана в openapi.json (OpenAPI 3.1) — импортируйте в Postman, Insomnia или генератор кода.
Изменения API и платформы анонсируются в чейнджлоге — ломающие изменения всегда отмечаются там первыми.
Аутентификация
Клиентские эндпоинты — App Secret
Отправляйте секрет вашего приложения в заголовке X-App-Secret. Он находится в Панель → ваше приложение. Секрет определяет, какому приложению принадлежит запрос.
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"}'
Админские эндпоинты — Bearer-токен
Аутентифицируйтесь на /api/admin/login.php, получите JWT и отправляйте его как 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"
Шифрованный конверт
Эндпоинты уровня SDK обмениваются конвертом AES-256-CBC + HMAC-SHA256 вместо обычного JSON. Формат на проводе: {"p": base64(IV || ciphertext), "t": unix_timestamp, "s": hmac_sha256_hex(p + t)} — ключи шифрования и подписи выводятся из секрета приложения, дополнительный обмен ключами не нужен.
{
"p": "aXYxNmJ5dGVzY2lwaGVydGV4dA…", // base64( IV || AES-256-CBC ciphertext )
"t": 1785671000, // unix timestamp (±300s accepted)
"s": "b7fd09…" // hmac_sha256_hex( p + t, mac_key )
}
Эндпоинты с пометкой Секрет приложения + шифрованный конверт требуют его для запроса и отвечают шифрованно. check-key.php определяет сам: отправьте обычный JSON — получите обычный JSON (именно поэтому работают curl-примеры на этой странице); отправьте конверт — ответ будет зашифрован.
Конверты старше ±300 секунд отклоняются, поэтому держите часы клиента достаточно точными. Вручную это писать не нужно: открытые примеры клиентов (VB.NET, C#, Python) содержат готовую реализацию CryptoEnvelope.
Как собирается конверт
Оба направления используют один рецепт. Из секрета приложения выводятся два ключа, так что у каждого приложения свои ключи шифрования и подписи:
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.
Каким эндпоинтам он нужен
На карточке каждого эндпоинта есть цветная метка аутентификации; эта таблица — та же информация одним взглядом:
| Модель аутентификации | Эндпоинты |
|---|---|
| Публичный | app/changelog · app/pricing · admin/login |
| Секрет приложения · обычный JSON или конверт | auth/check-key |
| App Secret | auth/trial · auth/request-hwid-reset · auth/account-register · auth/account-login · auth/change-password · update/validate · update/download |
| Секрет приложения + шифрованный конверт | auth/login · auth/heartbeat · auth/logout · app/text · app/slides · app/info · app/social-click · update/check |
| Bearer | admin/* |
| Секрет фулфилмента | app/fulfill |
Ответы и ошибки
Каждый ответ содержит булево success. Ошибки добавляют человекочитаемое message и стабильный машиночитаемый error_code:
{
"success": false,
"message": "This license key has been banned.",
"error_code": "BANNED"
}
| error_code | Значение |
|---|---|
MISSING_FIELDS | Отсутствует обязательное поле тела запроса. |
INVALID_KEY | Лицензионный ключ не существует для этого приложения. |
INVALID_CREDENTIALS | Пара логин/пароль отклонена (аккаунты пользователей + вход админа). |
HWID_MISMATCH | Ключ привязан к другому устройству. |
EXPIRED | Срок действия лицензии истёк. |
BANNED / PAUSED | Ключ забанен или приостановлен владельцем. |
MAINTENANCE | Приложение в режиме обслуживания. |
SESSION_EXPIRED / SESSION_MISMATCH | Heartbeat-сессия недействительна. |
TOO_MANY_ATTEMPTS | Блокировка перебора входа — аккаунт временно заблокирован; retry_after в ответе говорит, на сколько секунд. |
TRIAL_DISABLED / TRIAL_USED / TRIAL_LIMIT | Создание триала отклонено — отключено для этого приложения, уже использовано на этом устройстве или достигнут лимит на IP. |
HTTP-статусы
| error_code | Значение |
|---|---|
200 | Успех — результат в JSON-теле. |
400 | Валидация не пройдена — отсутствующие или неверные поля (см. error_code). |
401 | Отсутствует или неверен X-App-Secret / Bearer-токен. |
403 | Аутентифицирован, но не разрешено (чужое приложение, отозванный токен…). |
404 | Ресурс не найден. |
405 | Неверный HTTP-метод для этого эндпоинта. |
429 | Превышен лимит — подождите время из заголовка Retry-After перед повтором. |
500 | Ошибка сервера — сообщение намеренно общее; повторите позже. |
Лимиты запросов и честное использование
Общий лимитер по IP защищает каждый эндпоинт — при флуде вы получите 429 с заголовком Retry-After (у аутентифицированных админов потолок выше). Сверх этого — несколько точечных защит:
- Вход админа защищён от перебора — повторные неудачи временно блокируют аккаунт.
- Триалы ограничены на устройство (HWID) и на IP; превышение возвращает
TRIAL_LIMIT. - Перегенерация секрета ограничена по частоте на приложение, чтобы остановить случайные циклы ротации.
- Держите heartbeat на интервале из ответа login (по умолчанию 30 с) — чаще стучать бессмысленно.
Быстрый старт
Минимальная интеграция: проверьте ключ при запуске приложения, затем отправляйте heartbeat, чтобы поддерживать сессию.
# 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", … } }
Заметка: полный поток сессии (login → heartbeat → logout) использует шифрованный конверт, поэтому руками через curl его не пройти. Подключите его за минуты через Quick Start в панели (генерирует сниппеты на 9 языках с вашими реальными учётными данными) или через открытые примеры клиентов.
Тот же поток с официальным SDK
Вход, heartbeat и серверный kill-switch в несколько строк — SDK сам обрабатывает шифрованный конверт:
// 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
Лицензии и сессии
Активирует ключ при первом использовании, привязывает его к HWID устройства и открывает сессию. При последующих входах перепроверяет и открывает новую сессию. Соблюдает max_devices, закрывая самую старую сессию.
| Поле тела | Обяз. | Описание |
|---|---|---|
license_key | обязательно | Лицензионный ключ для активации / проверки. |
hwid | обязательно | Стабильный аппаратный отпечаток устройства. |
{
"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
}
Поддерживает сессию активной. Вызывайте каждые heartbeat_interval секунд (значение возвращает login). Перестанете вызывать — сессия будет закрыта на сервере.
| Поле тела | Обяз. | Описание |
|---|---|---|
session_id | обязательно | Сессия, возвращённая login. |
license_key | опционально | Если передан, сессия должна принадлежать этому ключу. |
{ "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
Немедленно закрывает сессию (например, при выходе из приложения). Тело: session_id обязательно, license_key опционально.
Лёгкая проверка статуса — без создания сессии и привязки HWID. Удобно для вопроса «этот ключ ещё действителен?».
| Поле тела | Обяз. | Описание |
|---|---|---|
license_key | обязательно | Ключ для проверки. |
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
}
}
Лёгкая проверка лицензии без привязки HWID и сессии — идеальна как предварительная проверка перед полным входом. Обычный JSON на входе и выходе.
| Поле тела | Обяз. | Описание |
|---|---|---|
license_key | обязательно | Ключ для проверки. |
Отправляет запрос на сброс HWID из диалога в вашем приложении, когда пользователь сменил машину. Владелец приложения одобряет его из панели.
| Поле тела | Обяз. | Описание |
|---|---|---|
license_key or username | обязательно | Определяет, чью привязку сбросить. |
reason | опционально | Заметка, которую увидит владелец. |
Бесплатные триалы
Выдаёт ограниченный по времени пробный ключ, привязанный к запросившему устройству. Один триал на HWID на приложение. Длительность настраивает владелец приложения.
| Поле тела | Обяз. | Описание |
|---|---|---|
hwid | обязательно | Отпечаток устройства, запрашивающего триал. |
{
"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": "…" }
}
Аккаунты пользователей
Предпочитаете вход по логину и паролю вместо голых ключей? PWF Auth включает полную модель аккаунтов с bcrypt-хешированием и привязкой к HWID.
Создаёт аккаунт конечного пользователя. Тело: username, password обязательно, email опционально.
| Поле тела | Обяз. | Описание |
|---|---|---|
username | обязательно | Желаемое имя пользователя (уникально в рамках приложения). |
password | обязательно | Пароль (хранится на сервере в виде хеша). |
email | опционально | Контактный e-mail аккаунта. |
Аутентифицирует и привязывает устройство. Тело: username, password, hwid обязательно. Возвращает ту же структуру сессии, что и login.
| Поле тела | Обяз. | Описание |
|---|---|---|
username | обязательно | Имя пользователя аккаунта. |
password | обязательно | Пароль аккаунта. |
hwid | обязательно | Отпечаток устройства для привязки сессии. |
Меняет пароль пользователя. Тело: username, current_password, new_password обязательно.
| Поле тела | Обяз. | Описание |
|---|---|---|
username | обязательно | Имя пользователя аккаунта. |
current_password | обязательно | Текущий пароль (проверяется перед сменой). |
new_password | обязательно | Новый пароль. |
Контент приложения и удалённое управление
Эти эндпоинты позволяют вашему приложению получать контент, который вы редактируете вживую в панели — тексты, слайды, цены, чейнджлог — без выпуска обновления.
Получает удалённый текст(ы). С ?name=… возвращает одну запись; без него — все тексты приложения. Переопределения на ключ важнее значений приложения. Лицензионный ключ передаётся в Authorization: Bearer
| Поле тела | Обяз. | Описание |
|---|---|---|
?name | опционально | Ключ текста для получения (опустите, чтобы получить все). |
Возвращает активные слайды-объявления приложения. Отправьте конверт с телом {"action":"get_slides"}; ответ зашифрован.
Метаданные приложения + соцссылки (имя, брендинг, URL). Ответ в конверте.
Увеличивает счётчик кликов соцссылки (для статистики вовлечённости в панели).
| Поле тела | Обяз. | Описание |
|---|---|---|
link_id | обязательно | Числовой id соцссылки. |
Публичная лента изменений одного приложения без аутентификации — рендерите виджет «Что нового» где угодно. Только опубликованные записи.
| Поле тела | Обяз. | Описание |
|---|---|---|
?app_id | обязательно | Приложение, чей чейнджлог читать. |
?limit | опционально | 1–50, по умолчанию 20. |
?since | опционально | ISO-дата — только записи, опубликованные с этой даты. |
?category | опционально | Фильтр: new / improved / fixed / removed / security / deprecated. |
Публичная витрина цен: уровни подписки и legacy-планы приложения; POST создаёт заказ на покупку; ?action=check читает активную подписку пользователя.
| Поле тела | Обяз. | Описание |
|---|---|---|
?app_id | обязательно | Приложение, чьи цены читать. |
?type | опционально | levels или plans (опустите для обоих). |
Серверный фулфилмент заказов для автоматических платёжных шлюзов — проверенный IPN завершает заказ и запускает генерацию + доставку ключей. Аутентификация общим секретом фулфилмента из настроек панели, никогда не пользовательской сессией.
| Поле тела | Обяз. | Описание |
|---|---|---|
order_id | обязательно | Заказ для фулфилмента (ORD-…). |
secret | обязательно | Ваш order_fulfill_secret. |
payment_ref | опционально | Опциональная платёжная ссылка шлюза. |
OTA-обновления
Спрашивает, доступна ли вызывающему более новая сборка — с учётом канала, фильтров ОС/архитектуры, минимальной версии и поэтапных раскаток (один и тот же клиент стабильно попадает в свою корзину).
| Поле тела | Обяз. | Описание |
|---|---|---|
v | обязательно | Текущая версия вызывающего (semver). |
channel | опционально | stable (по умолчанию), beta или alpha. |
os / arch | опционально | windows·macos·linux / x64·x86·arm64. |
hwid / license_key | опционально | Используется для стабильного распределения при раскатке. |
{
"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"
}
}
Отдаёт бинарник указанной версии. Используйте download_url из ответа check.php и сверяйте sha256 после загрузки.
Вебхуки
Превращайте события в HTTP-вызовы на ваш сервер: активации ключей, баны, истечения, заказы, новые обновления и другое. Настройте получателей на приложение (или на все приложения) в панели в разделе Application → Webhooks, выберите нужные события — и PWF Auth будет POST-ить подписанное JSON-тело на ваш URL. Доставка через очередь — ожидайте её в течение минуты-двух после события, не в тот же миг.
Тело доставки
{
"event": "key.activated",
"timestamp": "2026-08-20T14:07:02Z",
"data": {
"app_id": "01af6643-…",
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX",
"hwid": "A1B2C3…"
}
}
Заголовки доставки
| Заголовок | Описание |
|---|---|
X-Webhook-Id | Уникальный id доставки (whd_…). Не меняется между повторами одного события — используйте для дедупликации. |
X-Webhook-Timestamp | Unix-время попытки доставки. |
X-Webhook-Attempt | Счётчик попыток, начиная с 1. |
X-Webhook-Signature | Legacy-подпись: hex(HMAC-SHA256(body, secret)). |
X-Webhook-Signature-V2 | Предпочтительная подпись: t=<ts>,v1=hex(HMAC-SHA256(ts + "." + body, secret)) — метка времени внутри MAC делает повторы обнаружимыми. |
Проверка подписи
Всегда проверяйте перед тем как доверять доставке: вычислите V2 MAC над timestamp + "." + raw body с секретом вашего эндпоинта, сравните за константное время и отклоняйте устаревшие метки времени (±5 минут более чем достаточно). Отвечайте 2xx быстро — тяжёлая работа должна жить в вашей собственной очереди.
// 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
Повторы и политика отказов
- Доставка считается успешной при любом ответе
2xx/3xxв течение 5 секунд. - Отказы повторяются до 5 попыток с растущими интервалами: 1 мин → 5 мин → 30 мин → 2 ч → 6 ч.
X-Webhook-Idвыпускается один раз на событие и переиспользуется в каждом повторе — идемпотентность стоит одногоseen?-запроса.- Получатель, отказавший 20 раз подряд, автоматически ставится на паузу; включите его снова из панели (кнопка события
testпрямо там).
События
Подпишитесь на конкретные события или оставьте фильтр пустым, чтобы получать все. Поле event в теле говорит, какое из них сработало:
| Событие | Срабатывает когда |
|---|---|
key.created | Сгенерированы ключи (панель или admin API). |
key.activated | Первый успешный вход ключа привязывает его к устройству. |
key.banned / key.unbanned | Ключ забанен / разбанен. |
key.deleted | Ключ удалён. |
key.rotated | Строка ключа ротирована (старая строка перестаёт работать). |
key.suspected_leak | Детектор утечек пометил ключ как предположительно расшаренный/утёкший. |
key_expiring | Ключ приближается к истечению (плановая проверка). |
key_expired | Ключ истёк (плановая проверка). |
trial.created | Пробный ключ выдан новому устройству. |
hwid_reset.requested | Клиент запросил сброс устройства (HWID). |
new_order | Создан заказ на покупку. |
order.approved | Заказ одобрен и выполнен. |
subscription.* | Жизненный цикл подписки: создана / продлена / отменена / создан заказ на продление. |
update.published | Опубликована новая версия приложения. |
changelog.published | Запись чейнджлога стала публичной. |
app.revoked | Приложение отозвано / отключено. |
suspicious_activity | Сработала эвристика подозрительной активности. |
test | Ручная тестовая доставка из панели. |
Admin API
Серверные эндпоинты для управления приложениями и ключами. Все требуют токен Authorization: Bearer из эндпоинта входа ниже.
Не хотите хранить пароль в скрипте? Создайте Personal Access Token в Панель → Профиль → API Tokens и используйте его как значение Bearer (pwf_…). Он не истекает, пока вы его не отзовёте, работает на каждом эндпоинте /api/admin/* и намеренно не имеет доступа к управлению учётными данными (пароль, e-mail, 2FA, выпуск новых токенов).
Обменивает учётные данные на JWT. Если включена 2FA, возвращает requires_2fa + step1_token для завершения через /api/admin/totp.php.
| Поле тела | Обяз. | Описание |
|---|---|---|
username | обязательно | Имя пользователя админа. |
password | обязательно | Пароль админа. |
Массовая генерация лицензионных ключей. Тот же эндпоинт поддерживает GET (список), PUT (редактирование), DELETE и action-запросы вроде ?action=ban|pause|extend|reset-hwid и ?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}'
Админская поверхность также охватывает apps, sessions, updates, feature-flags, webhooks, analytics, audit, resellers и другое — всё под /api/admin/ с той же Bearer-аутентификацией. Войдите в панель, чтобы изучить их.
SDK
REST API работает из всего, что умеет отправлять HTTP-запросы. Официальные пакеты опубликованы в публичных реестрах — PWFAuth в NuGet (C# / VB.NET), pwfauth в npm (JavaScript / Node.js) и в PyPI (Python) — плюс расширение VS Code и полноценные примеры на PHP. Каждый SDK сам подключает шифрованный конверт, heartbeat и kill-switch.
- Открытые примеры клиентов (VB.NET · C# · Python) — полные потоки login/heartbeat/конверт, готовы к копированию
- Quick Start в панели — 5 шагов, генерирующих рабочие сниппеты на 9 языках с вашими реальными учётными данными
- Спецификация OpenAPI 3.1 (
openapi.json) — импорт в один клик в Postman / Insomnia или скормите её генератору кода
Готовы интегрироваться?
Создайте бесплатный аккаунт, зарегистрируйте приложение и скопируйте свой X-App-Secret из панели.