Overview
The Protector API is a REST API that answers in JSON. Every endpoint lives under one base address:
https://protector-bot.com/api/v1
/blacklist/{user_id}Is this Discord account on the Protector blacklist?
POST/linkIs this link a scam or phishing page?
POST/textExplicit words, fake Nitro gifts and dangerous links in a message.
POST/imageExplicit image detection (API Pass).
The API is served by protector-bot.com only. It never gives access to the machines that run the bot.
Get an API key
- Sign in on the developer page with Discord.
- Click Create a key and give it a name (for example the name of your bot).
- Copy the key right away: it starts with
pk_and is shown only once. Protector only keeps a fingerprint of it.
Lost a key, or think it leaked? Revoke it from the same page and create a new one. You can have up to 5 active keys.
The API Pass raises every limit and unlocks image analysis. It is bought from Protector's store in Discord, for 30 days, and is tied to your Discord account: your keys switch to the API Pass limits automatically. Each new purchase adds 30 days; a reminder arrives by private message 3 days before the end. Without a pass, your keys keep working on the free plan.
Authentication
Send your key in the Authorization header of every request:
Authorization: Bearer pk_your_key
Keep the key secret: never put it in a public repository or in code that runs in a visitor's browser.
Plans and rate limits
| Free | API Pass | |
|---|---|---|
| Requests per minute (per key) | 10 | 120 |
| Requests per month (per account) | 500 | 100,000 |
| Images per month | none | 3,000 |
| Blacklist, links, texts | yes | yes |
Monthly counters reset on the first day of each month (UTC). Reading the status of an image (GET /image/{id}) and GET /me do not count towards the monthly quota, only towards the per-minute limit.
Every response carries these headers:
X-RateLimit-Limit | Requests allowed per minute for this key. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute window resets (Unix timestamp). |
X-Quota-Limit / X-Quota-Remaining | Monthly quota of your account and what is left. |
Retry-After | On a 429, seconds to wait. |
Errors
An error returns a JSON body with a stable error code and a readable message:
{ "error": "rate_limited", "message": "Too many requests for this key. Wait before retrying.", "retry_after": 23 }
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Missing or malformed parameter (see detail). |
| 401 | unauthorized | Missing, wrong or revoked key. |
| 403 | plan_required | This endpoint needs the API Pass. |
| 404 | not_found | Unknown endpoint or image. |
| 405 | method_not_allowed | Wrong HTTP method. |
| 413 | payload_too_large | Body too large (JSON 64 KB, image 8 MB). |
| 415 | unsupported_media_type | Wrong Content-Type. |
| 429 | rate_limited / quota_exceeded | Per-minute limit or monthly quota reached. |
| 503 | unavailable | Detection rules are being loaded. Retry a bit later. |
Endpoints
GET /me
Your plan, its limits and your usage this month.
curl https://protector-bot.com/api/v1/me \
-H "Authorization: Bearer pk_your_key"
{
"plan": "pass",
"limits": { "per_minute": 120, "per_month": 100000, "images_per_month": 3000 },
"usage": { "month": "2026-10", "requests": 1834, "images": 41 },
"key": { "name": "My bot", "created_at": 1792150000 }
}
GET /blacklist/{user_id}
Tells whether a Discord account is on the Protector blacklist (accounts that took part in raids, nukes or scams, confirmed by the Protector team). The answer is only true or false: no reason, no evidence.
| Parameter | Type | Description |
|---|---|---|
user_id | path | Discord user ID (17 to 20 digits). |
curl https://protector-bot.com/api/v1/blacklist/123456789012345678 \
-H "Authorization: Bearer pk_your_key"
{ "user_id": "123456789012345678", "blacklisted": false }
A listed person can contest the decision on the appeal page. Do not use this answer as the only reason to sanction someone.
POST /link
Checks a link: known scam domains, look-alike domains (Cyrillic letters, punycode that read "discord" or "steam") and URL shorteners leading to a scam (the first redirect is followed).
| Field | Type | Description |
|---|---|---|
url | string | Address to check, http(s), up to 2,000 characters. Without a scheme, https:// is assumed. |
curl https://protector-bot.com/api/v1/link \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://dlscordnitro.com/gift"}'
{
"url": "https://dlscordnitro.com/gift",
"host": "dlscordnitro.com",
"dangerous": true,
"reason": "known_scam_domain",
"matched": "dlscordnitro.com",
"final_host": null
}
reason is one of known_scam_domain, lookalike_domain, shortener_to_scam, or null. free_host: true is added when the page sits on a free hosting service, where trap pages are often made: not dangerous by itself, but worth a closer look.
POST /text
Analyses a message the way Protector does in Discord: explicit words (even spelled with dots, spaces or numbers, like p.0.r.n), fake Nitro gifts and every link it contains. The text is not stored.
| Field | Type | Description |
|---|---|---|
text | string | The message, up to 4,000 characters (UTF-8). |
curl https://protector-bot.com/api/v1/text \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "free nitro for everyone https://dlscordnitro.com/gift"}'
{
"nsfw": { "flagged": false, "term": null },
"scam": { "flagged": true, "reason": "known_scam_domain" },
"links": [
{ "url": "https://dlscordnitro.com/gift", "host": "dlscordnitro.com", "dangerous": true,
"reason": "known_scam_domain", "matched": "dlscordnitro.com", "final_host": null }
]
}
Up to 20 links are analysed per message. scam.reason is the reason of the first dangerous link, or scam_pattern for a fake gift without a known link.
POST /image API Pass
Detects explicit images with Protector's image model (several frames are checked for an animated GIF, and long images are checked piece by piece). The analysis runs in the background: you get an ID, then you read the result.
Send the raw bytes of the image as the body, with the matching Content-Type: image/png, image/jpeg, image/gif or image/webp. 8 MB at most.
curl https://protector-bot.com/api/v1/image \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: image/png" \
--data-binary @picture.png
{ "id": "6f1c0e2a9b4d4c7e8a3f2b1c0d9e8f7a", "status": "queued",
"poll": "https://protector-bot.com/api/v1/image/6f1c0e2a9b4d4c7e8a3f2b1c0d9e8f7a" }
GET /image/{id}
Reads the result. Ask again every 1 to 2 seconds while status is queued or processing; it usually takes a few seconds.
{
"id": "6f1c0e2a9b4d4c7e8a3f2b1c0d9e8f7a",
"status": "done",
"created_at": 1792160000,
"result": {
"nsfw": false,
"label": "neutral",
"score": 0.9412,
"scores": { "drawing": 0.031, "hentai": 0.0021, "neutral": 0.9412, "porn": 0.0154, "sexy": 0.0103 },
"frames": 1
}
}
status is queued, processing, done or failed (then error says why, for example too_large_to_decode). The image is deleted as soon as it has been analysed; the result is kept for 24 hours.
Code examples
JavaScript (Node.js 18+)
const res = await fetch('https://protector-bot.com/api/v1/text', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PROTECTOR_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ text: message.content }),
});
const data = await res.json();
if (data.scam?.flagged || data.nsfw?.flagged) await message.delete();
Python
import os, requests
r = requests.get(
f"https://protector-bot.com/api/v1/blacklist/{member.id}",
headers={"Authorization": f"Bearer {os.environ['PROTECTOR_API_KEY']}"},
timeout=5,
)
if r.ok and r.json()["blacklisted"]:
print("Account on the Protector blacklist")
Fair use and privacy
- Texts and links you send are analysed on the fly and not stored. Images are deleted right after analysis; the result is kept 24 hours.
- Protector keeps, for your account: a fingerprint of each key, its name, its creation and last use dates, and the number of requests per month.
- The blacklist answer must not be the only basis of a sanction, nor be published or resold. Using the API to harass someone ends access to it.
- Details in the terms of use and the privacy policy.
API changelog
v1 (16 October 2026): first version. Blacklist, links, texts, images.
