Documentation

Protector API

Check Discord accounts, links, messages and images with the same detection engine that protects thousands of servers. One key, simple JSON, clear limits.

9 sections Updated Oct 16, 2026

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

The API is served by protector-bot.com only. It never gives access to the machines that run the bot.

Get an API key

  1. Sign in on the developer page with Discord.
  2. Click Create a key and give it a name (for example the name of your bot).
  3. 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

FreeAPI Pass
Requests per minute (per key)10120
Requests per month (per account)500100,000
Images per monthnone3,000
Blacklist, links, textsyesyes

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-LimitRequests allowed per minute for this key.
X-RateLimit-RemainingRequests left in the current minute.
X-RateLimit-ResetWhen the minute window resets (Unix timestamp).
X-Quota-Limit / X-Quota-RemainingMonthly quota of your account and what is left.
Retry-AfterOn 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 }
StatusCodeMeaning
400invalid_requestMissing or malformed parameter (see detail).
401unauthorizedMissing, wrong or revoked key.
403plan_requiredThis endpoint needs the API Pass.
404not_foundUnknown endpoint or image.
405method_not_allowedWrong HTTP method.
413payload_too_largeBody too large (JSON 64 KB, image 8 MB).
415unsupported_media_typeWrong Content-Type.
429rate_limited / quota_exceededPer-minute limit or monthly quota reached.
503unavailableDetection 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.

ParameterTypeDescription
user_idpathDiscord 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.

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).

FieldTypeDescription
urlstringAddress 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.

FieldTypeDescription
textstringThe 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.