A scoped REST API for stats, link checks, moderation and config, a realtime event stream, signed webhooks, ready-made SDKs and live SVG embeds — free for approved developers.
lp_sandboxThe public sandbox key works for anyone on every read endpoint and returns synthetic data — no sign-up, no Discord server, no approval. It’s prefilled in the Playground. Write endpoints (moderate, configscope) need a real key from your server’s Developer tab.
Developer access is granted per Discord account. Sign in, open Settings → Developer Accessand send a request — you’ll get a notification once it’s reviewed. Approved developers see a Developer tab in every server dashboard they manage, where API keys and webhooks are created.
API keys are created per server in that server’s Developer tab (up to 5 per server) and only reach that server’s data. Send the key in the X-Api-Key header (or Authorization: Bearer lp_…). Keys are shown once at creation and stored only as a hash — treat them like passwords.
Base URL: https://link-protect.com/api/v1 · Rate limit: 60 requests/minute per key (HTTP 429 beyond that).
Each key carries scopes, chosen when the key is created. Calling an endpoint without the required scope returns HTTP 403:
The sandbox key lp_sandbox has the read scope only and serves synthetic data — perfect for trying requests before creating a real key.
Live protection stats for the key’s server.
curl -H "X-Api-Key: lp_your_key" https://link-protect.com/api/v1/stats
{
"guildId": "1234567890",
"totalWarnings": 128,
"warnedUsers": 42,
"activeBlockers": 6,
"blockers": { "malware": true, "nitro": true, "invite": false, ... },
"thresholds": { "kick": 5, "ban": 10, "timeout": 3 }
}Daily action counts (1–60 days) plus totals and top reasons — the same data behind the dashboard chart.
curl -H "X-Api-Key: lp_your_key" "https://link-protect.com/api/v1/trends?days=7"
{
"days": 7,
"total": 23,
"perDay": [ { "date": "2026-07-17", "warned": 3, "kicked": 0, "banned": 0, "timeout": 1, "count": 4 }, ... ],
"topReasons": [ { "reason": "Posted a malware link", "count": 9 }, ... ],
"totals": { "warned": 18, "kicked": 2, "banned": 1, "timeout": 2 }
}Threat lookup against the Link Protect database + Google Safe Browsing — the engine behind the public link checker. With deep=1 the redirect chain is resolved server-side and every hop is checked.
curl -H "X-Api-Key: lp_your_key" "https://link-protect.com/api/v1/check?url=bit.ly/abc123&deep=1"
{
"url": "bit.ly/abc123",
"domain": "bit.ly",
"safe": false,
"category": "phishing",
"source": "threat-db",
"reason": "This link redirects to fake-login.ru, which is flagged as phishing…",
"seenOnServers": 14,
"redirects": [ { "url": "https://fake-login.ru/discord", "domain": "fake-login.ru", "status": 301 } ],
"finalDomain": "fake-login.ru"
}Check up to 25 URLs in one request — same verdict shape as the single check, one entry per URL.
curl -X POST -H "X-Api-Key: lp_sandbox" -H "Content-Type: application/json" \
-d '{"urls": ["bit.ly/abc123", "https://example.com"]}' \
https://link-protect.com/api/v1/check/batchThe warning record of one member on the key’s server — count, reasons and where they stand against the kick/ban thresholds.
curl -H "X-Api-Key: lp_sandbox" https://link-protect.com/api/v1/warns/9876543210
Moderate a member from your own tooling. action is one of warn · timeout · untimeout · kick · ban · unban; minutes sets the timeout length, reason lands in the audit log.
curl -X POST -H "X-Api-Key: lp_your_key" -H "Content-Type: application/json" \
-d '{"userId": "9876543210", "action": "timeout", "minutes": 60, "reason": "Spam"}' \
https://link-protect.com/api/v1/moderateToggle one of the link blockers (malware, nitro, invite, … — the same ids the stats endpoint returns).
curl -X POST -H "X-Api-Key: lp_your_key" -H "Content-Type: application/json" \
-d '{"blocker": "nitro", "enabled": true}' \
https://link-protect.com/api/v1/blockerAdd or remove a domain/link on the server’s custom blacklist — action is add or remove.
curl -X POST -H "X-Api-Key: lp_your_key" -H "Content-Type: application/json" \
-d '{"action": "add", "link": "scam-site.ru"}' \
https://link-protect.com/api/v1/blacklistSwitch emergency lockdown on or off — the same big red button as the dashboard, scriptable.
curl -X POST -H "X-Api-Key: lp_your_key" -H "Content-Type: application/json" \
-d '{"active": true, "reason": "Raid in progress"}' \
https://link-protect.com/api/v1/lockdownThe full OpenAPI 3 spec of the public API — no key required. Feed it to your client generator or import it into Postman/Insomnia: link-protect.com/api/v1/openapi.json.
GET /api/v1/events/stream is a Server-Sent Eventsstream of your server’s moderation events (the same six event types webhooks deliver) — ideal when you can’t host a public webhook endpoint. Auth works via the usual X-Api-Key header, or a ?key= query param for browser EventSource clients:
const es = new EventSource(
"https://link-protect.com/api/v1/events/stream?key=lp_your_key"
);
es.onmessage = (e) => {
const event = JSON.parse(e.data); // { event: "link_blocked", guildId, data, … }
console.log(event.event, event.data);
};Limits: 2 concurrent streams per key, and each connection is closed after 30 minutes — EventSource reconnects automatically.
Fire real requests from your browser — prefilled with the sandbox key lp_sandbox, so everything read-only works instantly. Paste your own key to hit your server (moderate/config calls are live — they really moderate).
GET /api/v1/statsscope: readLive protection statsTiny zero-dependency clients for the whole v1 API — REST calls, the event stream and a webhook signature verification helper are included in both.
import { LinkProtect } from "./linkprotect.js";
const lp = new LinkProtect("lp_your_key");
const stats = await lp.stats();
const verdict = await lp.check("bit.ly/abc123");
await lp.moderate({ userId: "9876543210", action: "warn" });
// Express: verify webhook deliveries
lp.verifySignature(rawBody, req.headers["x-linkprotect-signature"], "whsec_…");from linkprotect import LinkProtect
lp = LinkProtect("lp_your_key")
stats = lp.stats()
verdict = lp.check("bit.ly/abc123")
lp.moderate(user_id="9876543210", action="warn")
# Flask/FastAPI: verify webhook deliveries
lp.verify_signature(raw_body, signature_header, "whsec_…")Register up to 3 HTTPS endpoints per server in the Developer tab and pick the events you care about. Deliveries are POSTs with a JSON body, sent within ~10 seconds of the event:
POST https://your-server.com/linkprotect-hook
Content-Type: application/json
X-LinkProtect-Event: link_blocked
X-LinkProtect-Signature: sha256=8f3a…
{
"event": "link_blocked",
"guildId": "1234567890",
"data": {
"user_id": "9876543210", "username": "scammer42", "channel_id": "111222333",
"action": "warned", "reason": "Posted a malware link", "warn_count": 2,
"timestamp": 1784800000
},
"sentAt": 1784800005
}Every delivery is signed: X-LinkProtect-Signatureis the hex HMAC-SHA256 of the raw request body, keyed with your webhook’s whsec_… secret. Verify before trusting:
// Node.js
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}Respond with any 2xx within 6 seconds. Failed deliveries count up — after 25 consecutive failures the webhook is disabled automatically (re-enable it in the Developer tab, which also resets the counter). The Developer tab keeps a delivery log (last 50, with status and latency) per webhook, and its Send test event control delivers a realistic sample of any event type to your endpoint on demand.
Live SVG widgets — no key required, cacheable, safe to hotlink:
<!-- Protected-by badge (style=light for bright pages) --> <img src="https://link-protect.com/api/badge?guild=YOUR_SERVER_ID" alt="Protected by Link Protect"> <!-- Live stats card --> <img src="https://link-protect.com/api/embed/stats?guild=YOUR_SERVER_ID" alt="Link Protect stats"> <!-- Voter leaderboard (limit 3–10) --> <img src="https://link-protect.com/api/embed/leaderboard?limit=5" alt="Top voters">
The platform grows with what developers actually need — send a feature request from any server dashboard (Report → Feedback) or join the beta programme in the Developer tab.
Request developer access