Перейти к основному содержимому

API статуса PIN

GET /v1/pins/:pinCode/status

API статуса PIN позволяет следить за ходом сканирования в реальном времени. Он возвращает текущий статус, процент выполнения, сообщение о статусе и сводные результаты после завершения. Подходит для индикаторов прогресса, живых дашбордов и интеграций с Discord-ботами.

Базовый URL
https://api.anticheat.ac/v1
Аутентификация
Требуется API-ключ с разрешением pins:status

Получить статус PIN

Получите текущий статус сканирования для конкретного PIN, включая процент выполнения и сообщение о статусе. Доступ есть только к статусу PIN, которыми вы владеете (созданным вашим аккаунтом). После завершения сканирования ответ также содержит сводку результатов с количеством детектов.

GET/v1/pins/:pinCode/status

Параметры

НазваниеТипОписание
pinCodestring8-символьный код PIN (например, A7K3M2P9)

Заголовки

x-api-key: your_api_key_here

Ответ (ожидание)

{
  "pin": "A7K3M2P9",
  "pinName": "Tournament Match #42",
  "type": "Java",
  "status": "pending",
  "progress": 0,
  "statusMessage": null,
  "result": null,
  "used": false,
  "lastStatusUpdate": null,
  "createdAt": "2026-02-11T15:25:00.000Z",
  "isFinished": false,
  "isScanning": false,
  "isPending": true
}

Ответ (сканирование — в процессе)

{
  "pin": "A7K3M2P9",
  "pinName": "Tournament Match #42",
  "type": "Java",
  "status": "scanning",
  "progress": 45,
  "statusMessage": "Scanning system files... (45%)",
  "result": null,
  "used": true,
  "lastStatusUpdate": "2026-02-11T15:30:00.000Z",
  "createdAt": "2026-02-11T15:25:00.000Z",
  "isFinished": false,
  "isScanning": true,
  "isPending": false
}

Ответ (завершено)

После завершения сканирования ответ содержит data объект со сводкой количества детектов. Полные данные об обнаружениях смотрите в эндпоинте результатов PIN.

{
  "pin": "A7K3M2P9",
  "pinName": "Tournament Match #42",
  "type": "Java",
  "status": "finished",
  "progress": 100,
  "statusMessage": "Scan completed",
  "result": "cheating",
  "used": true,
  "lastStatusUpdate": "2026-02-11T15:35:00.000Z",
  "createdAt": "2026-02-11T15:25:00.000Z",
  "isFinished": true,
  "isScanning": false,
  "isPending": false,
  "data": {
    "cheating": "cheating",
    "vpn": "No",
    "country": "US",
    "scantime": "45 seconds",
    "windows": "Windows 11 Pro 23H2",
    "detectionsCount": 3,
    "warningsCount": 1,
    "suspiciousCount": 2,
    "discord": [
      { "id": "123456789012345678", "username": "player123" }
    ]
  }
}

Поля ответа

ПолеТипОписание
pinstring8-символьный код PIN
pinNamestring | nullСвоё название, присвоенное PIN
typestringТип сканирования (Java, Bedrock, FiveM и т. д.)
statusstringТекущий статус: pending, scanning, finished, expired или error
progressnumberХод сканирования от 0 до 100
statusMessagestring | nullПонятное сообщение о текущем этапе сканирования
resultstring | nullВердикт сканирования: legit, cheating, suspicious или null, если не завершено
usedbooleanИспользован ли PIN (началось ли сканирование)
lastStatusUpdatestring | nullМетка времени ISO 8601 последнего обновления статуса
createdAtstringМетка времени ISO 8601, когда был создан PIN
isFinishedbooleanУдобный флаг: true, когда статус равен "finished"
isScanningbooleanУдобный флаг: true, когда статус равен "scanning"
isPendingbooleanУдобный флаг: true, когда статус равен "pending"

Поля данных (только после завершения)

ПолеТипОписание
cheatingstring | nullОбщий вердикт о читерстве
vpnstring | nullСтатус обнаружения VPN
countrystring | nullСтрана проверяемого пользователя
scantimestring | nullСколько длилось сканирование
windowsstring | nullИнформация о версии Windows
detectionsCountnumberЧисло подтверждённых детектов читов
warningsCountnumberЧисло флагов предупреждений
suspiciousCountnumberЧисло подозрительных находок
discordarrayОбнаруженные аккаунты Discord. Каждая запись содержит id и username

Ответы с ошибками

СтатусКодОписание
400Неверный запросКод PIN пуст или недействителен
403Доступ запрещёнЭтот PIN не принадлежит вашему аккаунту
404Не найденоКод PIN не существует

Нужно быть владельцем

Вы можете получать статус только для PIN, созданных вашим аккаунтом. При попытке получить доступ к PIN другого пользователя API вернёт ошибку 403 Forbidden.

Отличие от результатов PIN

Этот эндпоинт оптимизирован для опроса во время сканирования. Он возвращает данные о ходе выполнения и лёгкую сводку после завершения. Полные данные об обнаружениях (отдельные детекты, подозрительные элементы, предупреждения, проверки целостности) смотрите в эндпоинте результатов PIN после завершения сканирования.

Стратегия опроса

Поскольку сканирование занимает время, опрашивайте этот эндпоинт периодически, чтобы отслеживать прогресс. Рекомендуемые стратегии:

СтратегияИнтервалПрименение
Индикатор прогресса3–5 секундОтображение прогресса в реальном времени в интерфейсе или во встраивании Discord
Фоновая проверка10–15 секундБот ждёт результатов, чтобы отправить уведомление
Пакетный мониторинг30–60 секундОдновременный мониторинг множества PIN

Учёт лимита запросов

API допускает 1 000 запросов в час на API-ключ. Если опрашивать каждые 3 секунды, сканирование одного PIN расходует около 20 запросов в минуту. Выбирайте интервал опроса с учётом того, сколько PIN вы отслеживаете одновременно.

Пример использования

cURL

curl -X GET "https://api.anticheat.ac/v1/pins/A7K3M2P9/status" \
  -H "x-api-key: your_api_key_here"

JavaScript / Node.js

const response = await fetch('https://api.anticheat.ac/v1/pins/A7K3M2P9/status', {
  headers: { 'x-api-key': 'your_api_key_here' }
});

const data = await response.json();

console.log('Status:', data.status);
console.log('Progress:', data.progress + '%');
console.log('Message:', data.statusMessage);

if (data.isFinished) {
  console.log('Result:', data.result);
  console.log('Detections:', data.data.detectionsCount);
}

Python

import requests

response = requests.get(
    'https://api.anticheat.ac/v1/pins/A7K3M2P9/status',
    headers={'x-api-key': 'your_api_key_here'}
)

data = response.json()

print(f"Status: {data['status']}")
print(f"Progress: {data['progress']}%")
print(f"Message: {data.get('statusMessage', 'N/A')}")

if data['isFinished']:
    print(f"Result: {data['result']}")
    print(f"Detections: {data['data']['detectionsCount']}")

Опрос с индикатором прогресса (JavaScript)

async function pollPinStatus(pinCode, apiKey, onProgress) {
  const url = 'https://api.anticheat.ac/v1/pins/' + pinCode + '/status';
  const headers = { 'x-api-key': apiKey };

  while (true) {
    const res = await fetch(url, { headers });
    const data = await res.json();

    onProgress({
      status: data.status,
      progress: data.progress,
      message: data.statusMessage,
    });

    if (data.isFinished) return data;

    if (data.status === 'expired' || data.status === 'error') {
      throw new Error('Scan ' + data.status);
    }

    await new Promise(r => setTimeout(r, 3000));
  }
}

const result = await pollPinStatus('A7K3M2P9', 'your_api_key_here', (info) => {
  console.log('[' + info.progress + '%] ' + info.message);
});

console.log('Final result:', result.result);
console.log('Detections:', result.data.detectionsCount);

Пример Discord-бота (discord.js)

const { EmbedBuilder } = require('discord.js');

async function trackScan(channel, pinCode, apiKey) {
  const url = 'https://api.anticheat.ac/v1/pins/' + pinCode + '/status';
  const headers = { 'x-api-key': apiKey };

  const embed = new EmbedBuilder()
    .setTitle('Scan: ' + pinCode)
    .setDescription('Starting scan...')
    .setColor(0x3498db);

  const msg = await channel.send({ embeds: [embed] });

  const interval = setInterval(async () => {
    try {
      const res = await fetch(url, { headers });
      const data = await res.json();

      const bar = '\u2588'.repeat(Math.floor(data.progress / 5))
        + '\u2591'.repeat(20 - Math.floor(data.progress / 5));

      embed.setDescription(
        bar + ' ' + data.progress + '%\n'
        + (data.statusMessage || 'Waiting...')
      );

      if (data.isFinished) {
        clearInterval(interval);
        embed.setColor(data.result === 'legit' ? 0x2ecc71 : 0xe74c3c);
        embed.addFields(
          { name: 'Result', value: data.result, inline: true },
          { name: 'Detections', value: String(data.data.detectionsCount), inline: true },
          { name: 'Warnings', value: String(data.data.warningsCount), inline: true },
        );
      }

      await msg.edit({ embeds: [embed] });
    } catch (err) {
      clearInterval(interval);
      embed.setDescription('Error: ' + err.message).setColor(0xe74c3c);
      await msg.edit({ embeds: [embed] });
    }
  }, 5000);
}