API Reference
Integrate invisible bot & proxy detection into your product. No CAPTCHAs. No friction. Under 40ms per evaluation.
Quick Start
From zero to working integration in 5 minutes. You need your API key from the dashboard.
Loading...
This is the URL your backend calls. Your API key authenticates the request.
// ─── STEP 1: Add SDK to your HTML <head> ───────────────────────────────────── <script async src="loading..." id="_mcl"></script> <form class="monocle-enriched" id="login-form"> <input type="email" name="email" /> <!-- SDK auto-injects: <input type="hidden" name="monocle" value="TOKEN" /> --> </form> // ─── STEP 2: Read token in your frontend JS ─────────────────────────────────── document.getElementById('login-form').addEventListener('submit', async (e) => { e.preventDefault(); const sentinelToken = document.querySelector('input[name="monocle"]')?.value; // Send to YOUR backend (never call Sentinel directly from the browser) await fetch('/your-login-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, sentinelToken }) }); }); // ─── STEP 3: Evaluate on your backend (Node.js) ────────────────────────────── app.post('/your-login-endpoint', async (req, res) => { const { email, sentinelToken } = req.body; const result = await fetch('LOADING/v1/evaluate', { method: 'POST', headers: { 'Authorization': 'Bearer sk_live_YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ token: sentinelToken }) }); const data = await result.json(); if (data.isSuspicious) { return res.status(403).json({ error: 'Bot or proxy detected.' }); } // ✅ Connection is clean — proceed res.json({ success: true }); });
How It Works
Sentinel uses a 3-step Client → Your Backend → Sentinel API flow to keep your secret key off the browser.
Browser Collection
The Sentinel SDK runs invisibly in your user's browser, collecting telemetry. It injects an encrypted token into your forms.
Token Forwarded
Your frontend submits the token to your own backend server along with the rest of the form data.
API Evaluation
Your backend calls POST /v1/evaluate with your secret key. Sentinel returns a threat intelligence report instantly.
Authentication
All requests to /v1/evaluate must include your secret API key as a Bearer token in the Authorization header. Find your key in the Dashboard.
Keep your key secret
Never put sk_live_... in your HTML, JavaScript, or any client-side code. Only use it in your backend server environment.
Embed the SDK
Add the Sentinel Edge SDK to every page where you want to evaluate users. It runs silently and generates a token. Copy the exact script below — the key is already configured for your account.
<!-- Sentinel Edge SDK — paste inside <head> --> <script async src="loading..." id="_mcl"></script> <!-- Add class="monocle-enriched" to any form you want evaluated --> <form class="monocle-enriched" id="my-form"> <!-- The SDK injects this automatically: --> <input type="hidden" name="monocle" value="eyJ..." /> </form>
The SDK takes ~1–2 seconds to load and generate the token. The hidden input will be empty until then.
Collect the Token
When your form is submitted, read the monocle hidden input and forward it to your backend. Guard against the case where the SDK hasn't loaded yet.
document.getElementById('my-form').addEventListener('submit', async (e) => { e.preventDefault(); // Read the token injected by the Sentinel SDK const sentinelToken = document.querySelector('input[name="monocle"]')?.value; if (!sentinelToken) { // SDK is still loading — ask user to try again return showError('Security check loading. Please try again.'); } // Forward to your backend with the rest of the form data const res = await fetch('/your-backend-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: e.target.email.value, sentinelToken // ← pass this to your backend }) }); });
Call the Evaluate Endpoint
loading...
Call this from your backend server — never from the browser. Pass the token from the client and your secret API key. The response tells you everything about the connection in under 40ms.
Request Body
The encrypted token from the client's input[name="monocle"] field.
const response = await fetch('LOADING/v1/evaluate', { method: 'POST', headers: { 'Authorization': 'Bearer sk_live_YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ token: req.body.sentinelToken // from the form submission }) }); const data = await response.json(); // data.isSuspicious → true if VPN/proxy/bot detected // data.details → full forensic breakdown if (data.isSuspicious) { return res.status(403).json({ error: 'Suspicious connection.' }); }
import requests response = requests.post( 'LOADING/v1/evaluate', headers={ 'Authorization': 'Bearer sk_live_YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'token': sentinel_token # from the form POST body } ) data = response.json() if data['isSuspicious']: return '403 Suspicious connection', 403
curl -X POST 'LOADING/v1/evaluate' \ -H 'Authorization: Bearer sk_live_YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"token": "eyJ..."}'
$ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => 'LOADING/v1/evaluate', CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer sk_live_YOUR_API_KEY', 'Content-Type: application/json' ], CURLOPT_POSTFIELDS => json_encode([ 'token' => $_POST['sentinelToken'] ]) ]); $data = json_decode(curl_exec($ch), true); if ($data['isSuspicious']) { http_response_code(403); exit(); }
Response Object
A successful call returns 200 OK with this JSON structure.
| Field | Type | Description |
|---|---|---|
| isSuspicious | boolean | Master flag. true if VPN, proxy, or bot detected. Use this for quick blocking logic. |
| details.ip | string | The unmasked, real IP address of the user. |
| details.cc | string | ISO 3166-1 country code (e.g. "US", "EE"). |
| details.vpn | boolean | Commercial VPN detected (NordVPN, Proton, etc.). |
| details.proxied | boolean | Traffic routed through a residential or datacenter proxy. |
| details.anonymized | boolean | Any anonymization layer detected (Tor, etc.). |
| details.service | string | Identified provider name (e.g. "PROTON_VPN", "BRIGHT_DATA"). |
{
"status": "success",
"isSuspicious": true,
"details": {
"ip": "185.107.80.12",
"cc": "EE",
"vpn": true,
"proxied": false,
"anonymized": true,
"dch": false,
"service": "PROTON_VPN"
}
}
{
"status": "success",
"isSuspicious": false,
"details": {
"ip": "82.131.45.9",
"cc": "DE",
"vpn": false,
"proxied": false,
"service": "DEUTSCHE_TELEKOM"
}
}
Rate Limits
Limits apply per API key per month. Exceeding returns 429. Check your usage in the Dashboard.
| Plan | Monthly Limit |
|---|---|
| Developer | 10,000 requests |
| Pro Growth | 100,000 requests |
| Enterprise | Unlimited |
Error Codes
Standard HTTP status codes. All error responses include an error string field.
-
400
Bad Request — Missing or invalid
token. - 401 Unauthorized — Invalid or missing API key.
- 429 Rate Limited — Monthly quota exceeded.
- 500 Server Error — Token tampered with or expired.