The Pin Status API allows you to monitor the real-time progress of a scan. Get the current status, progress percentage, status message, and summary results once the scan finishes. Ideal for building progress bars, live dashboards, and Discord bot integrations.
Base URL: https://api.anticheat.ac/v1
Authentication: API Key required with pins:status permission
Retrieve the current scan status for a specific pin, including progress percentage and status message. You can only access status for pins that you own (created by your account). When the scan finishes, the response also includes a summary of the results with detection counts.
/v1/pins/:pinCode/status| Name | Type | Description |
|---|---|---|
| pinCode | string | The 8-character pin code (e.g. 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
}When the scan completes, the response includes a data object with a summary of detection counts. For full detection details, use the Pin Results endpoint.
{
"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" }
]
}
}| Field | Type | Description |
|---|---|---|
| pin | string | The 8-character pin code |
| pinName | string | null | Custom name assigned to the pin |
| type | string | Scan type (Java, Bedrock, FiveM, etc.) |
| status | string | Current status: pending, scanning, finished, expired, or error |
| progress | number | Scan progress from 0 to 100 |
| statusMessage | string | null | Human-readable message describing current scan step |
| result | string | null | Scan verdict: legit, cheating, suspicious, or null if not finished |
| used | boolean | Whether the pin has been used (scan started) |
| lastStatusUpdate | string | null | ISO 8601 timestamp of the last status update |
| createdAt | string | ISO 8601 timestamp when the pin was created |
| isFinished | boolean | Convenience flag: true when status is "finished" |
| isScanning | boolean | Convenience flag: true when status is "scanning" |
| isPending | boolean | Convenience flag: true when status is "pending" |
| Field | Type | Description |
|---|---|---|
| cheating | string | null | Overall cheating verdict |
| vpn | string | null | VPN detection status |
| country | string | null | Country of the scanned user |
| scantime | string | null | How long the scan took |
| windows | string | null | Windows version information |
| detectionsCount | number | Number of confirmed cheat detections |
| warningsCount | number | Number of warning flags |
| suspiciousCount | number | Number of suspicious findings |
| discord | array | Discord accounts detected. Each entry has id and username |
| Status | Code | Description |
|---|---|---|
400 | Bad Request | Pin code is empty or invalid |
403 | Forbidden | The pin does not belong to your account |
404 | Not Found | Pin code does not exist |
You can only retrieve status for pins created by your own account. Attempting to access another user's pin will return a 403 Forbidden error.
This endpoint is optimized for polling during a scan. It returns progress data and a lightweight summary when finished. For full detection details (individual detections, suspicious items, warnings, integrity checks), use the Pin Results endpoint after the scan completes.
Since scans take time to complete, you should poll this endpoint periodically to track progress. Here are some recommended strategies:
| Strategy | Interval | Use Case |
|---|---|---|
| Progress bar | 3-5 seconds | Real-time progress display in a UI or Discord embed |
| Background check | 10-15 seconds | Bot waiting for results to send a notification |
| Batch monitoring | 30-60 seconds | Monitoring many pins simultaneously |
The API allows 1,000 requests per hour per API key. If you poll every 3 seconds, a single pin scan uses ~20 requests per minute. Plan your polling interval based on how many pins you monitor simultaneously.
curl -X GET "https://api.anticheat.ac/v1/pins/A7K3M2P9/status" \ -H "x-api-key: your_api_key_here"
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);
}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']}")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);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);
}