API Documentation
22 behavioral signals for detection. 20 for verification. Two products, one API.
Quick Start
1 Get a free API key at /api-dashboard
2 Add the collector to your page (for detection) or POST events directly (for verification)
3 Call /api/score or /api/verify-bot
Bot Detection Endpoints
Score a set of behavioral events. Returns a full score report with verdict and intent classification.
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
X-API-Key | Recommended | Your API key (detlab_...). Required for rate limit tracking and credit deduction. |
X-Request-ID | No | Optional request ID for tracing. Auto-generated if omitted. |
Request Body
Response (200)
curl Example
Create a free Sandbox API key (100 evaluations/month).
Request
Response (200)
List all API keys for an email address (keys are masked).
Get usage logs for a specific API key.
Create a Stripe checkout session for Pro ($29/mo) or Scale ($99/mo).
Request
Bot Verification Endpoints
Verify an entity IS a bot. Inverted scoring — machine precision, sustained throughput, and autonomous behavior score HIGH. Returns a verdict, bot type classification, and optional JWT trust token.
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
X-API-Key | Yes | Your API key. Required for trust token generation. |
X-Ephemeral | No | Set to true for ephemeral mode. If HUMAN_DETECTED, signal breakdown is omitted from response. |
X-Request-ID | No | Optional request ID for tracing. |
Request Body
Response (200)
Create a new continuous bot verification session. Stream events over time and get live verdict updates.
Request Body
Response (200)
If webhook_url is provided, Detection Lab will POST to it when the verdict changes (e.g., BOT_VERIFIED flips to HUMAN_DETECTED).
Append events to an existing continuous session. Each call re-scores with accumulated data.
Request Body
Response (200)
Get the current state and verdict of a continuous session.
Response (200)
Bot Verification Verdicts
| Verdict | Score | Meaning | Suggested Action |
|---|---|---|---|
BOT_VERIFIED | 70+ | Confirmed autonomous bot behavior | Issue trust token, allow agent access |
UNCERTAIN | 40-69 | Mixed signals, could be remote-controlled | Request more events or flag for review |
HUMAN_DETECTED | <40 | Human behavioral patterns detected | Deny bot-only access, may be human LARPing |
Bot Type Classification
When a bot is verified, the bot_type field classifies it into one of four archetypes:
| Bot Type | Description | Detection Pattern |
|---|---|---|
autonomous_agent | Fully autonomous AI agent | High body + high mind scores |
human_larping | Human pretending to be a bot | Low body (biological tremor, overshoot) |
remote_controlled | Bot with human oversight | High body, low mind (human decision pauses) |
replay_bot | Replayed recorded sessions | Identical paths, single-human timing |
Trust Tokens (JWT)
When /api/verify-bot returns BOT_VERIFIED and the request includes an X-API-Key, a signed JWT trust token is included in the response. Downstream services can validate this token without calling Detection Lab again.
Token Claims
| Claim | Type | Description |
|---|---|---|
verdict | string | BOT_VERIFIED, UNCERTAIN, or HUMAN_DETECTED |
overall_score | float | Composite verification score (0-100) |
bot_type | string | Classification (autonomous_agent, etc.) |
iat | int | Issued-at timestamp (Unix epoch) |
exp | int | Expiration timestamp (default: 1 hour TTL) |
iss | string | detectionlab.app |
Validation Example
Detection Verdicts
| Verdict | Score | Meaning | Suggested Action |
|---|---|---|---|
PASS | 70+ | Genuine human behavior | Allow request |
MARGINAL | 50-69 | Suspicious but inconclusive | Rate limit or flag for review |
FAIL | <50 | Bot detected | Block or challenge |
Intent Classification
When a bot is detected (FAIL or MARGINAL), the intent field tells you what kind of bot it is:
| Intent | Description | Suggested Response |
|---|---|---|
human | Genuine human behavior | Allow |
credential_stuffing | Rapid automated form-filling | Block + alert security |
scraping | Content extraction | Rate limit |
spam_submission | Template/AI-generated text | Block or flag |
account_takeover | Polished automation with stolen creds | Block + MFA challenge |
replay_attack | Replayed recorded sessions | Block + invalidate session |
framework_automation | Selenium/Playwright/Puppeteer | Block |
click_fraud | Automated ad/button clicking | Block + report |
unknown_bot | Bot detected, intent unclear | Flag for investigation |
Detection Signals (22)
Each signal is scored 0-100. A score above 70 means human-like behavior for that signal.
Verification Signals (20)
Each signal is scored 0-100. A score above 70 means bot-like behavior for that signal (inverted from detection).
Event Types
The collector captures these event types automatically. If building a custom collector, your events must include these fields:
| Type | Required Fields |
|---|---|
mousemove | x, y, isTrusted, timestamp_ms |
click | x, y, elem_center_x, elem_center_y, element_id, isTrusted, timestamp_ms |
keydown | key, delay_ms, isTrusted, timestamp_ms |
scroll | delta_y, delta_mode, pause_after_ms, scroll_y, isTrusted, timestamp_ms |
hover | element_id, isTrusted, timestamp_ms |
fingerprint | data (object), timestamp_ms |
page_enter | page, word_count, timestamp_ms |
page_leave | page, timestamp_ms |
Rate Limits
Bot Detection
| Tier | Price | Evaluations/month | Rate Limit |
|---|---|---|---|
| Sandbox (free) | $0 | 100 | 10 req/min |
| Pro | $29/mo | 10,000 | 100 req/min |
| Scale | $99/mo | 100,000 | 500 req/min |
| Enterprise | Custom | Unlimited | 1,000 req/min |
Bot Verification
| Tier | Price | Verifications/month | Rate Limit |
|---|---|---|---|
| Sandbox (free) | $0 | 50 | 5 req/min |
| Startup | $49/mo | 5,000 | 50 req/min |
| Scale | $199/mo | 100,000 | 200 req/min |
| Enterprise | Custom | Unlimited | Custom |
Rate limit headers are returned with authenticated requests:
X-RateLimit-Limit— max requests per minuteX-RateLimit-Remaining— remaining requestsX-RateLimit-Reset— unix timestamp when limit resets
Error Responses
| Code | Body | Cause |
|---|---|---|
| 400 | {"error": "no data"} | Empty request body |
| 400 | {"error": "no events"} | Events array is empty |
| 404 | {"error": "session not found"} | Invalid session ID for continuous sessions |
| 429 | {"error": "Rate limit exceeded"} | Too many requests |