Reference
API Reference
Three endpoints. The first two are called by the widget in the browser, the third by your server. All responses are JSON. Base URL is your instance origin, e.g. https://your-instance.com/api.
| Endpoint | Method | Called by | Purpose |
|---|---|---|---|
| /api/api.js | GET | Browser | Serves the widget script |
| /api/generate-token | POST | Widget | Score the visitor, mint a token |
| /api/verify-token | GET / POST | Your server | Validate a token with your secret key |
GET /api/api.js
Returns the widget script (application/javascript, Cache-Control: public, max-age=3600). Also available as a static file at /js/aiCaptcha.js. Embed it with <script src="…" async>.
POST /api/generate-token
Called automatically by the widget. Validates your site key, runs the AI scoring engine, and returns a one-time token valid for 2 minutes.
Request
bash
curl -X POST https://your-instance.com/api/generate-token \
-H "Content-Type: application/json" \
-H "Origin: https://your-registered-domain.com" \
-d '{
"site_key": "IZAAAAA...",
"timezone": "Asia/Jakarta",
"screen": { "width": 1920, "height": 1080 },
"language": "en-US",
"mouse_entropy": [ ... ],
"interaction_speed": [ ... ]
}'| Field | Type | Description |
|---|---|---|
site_key | string, required | Public site key from the dashboard. |
timezone | string | Visitor timezone (Intl API). |
screen | object | Screen metrics: width, height, availWidth, availHeight, colorDepth, pixelDepth. |
language | string | Browser language. |
mouse_entropy | array | Mouse movement samples {speed, xDiff, yDiff, x, y} — max 30 points, collected while the visitor moves. |
interaction_speed | array | Keystroke interval samples (ms) — max 10, filtered to 20–1000 ms. |
Responses
200 OK
{ "token": "aJEcqQq0OkWW7TTjNh1Sk6KpZG8...", "verified": true, "score": 0.87 }400 Bad Request
{ "error": "Invalid site key" }429 Too Many Requests
{ "error": "Too many requests. Please try again later." }GET|POST /api/verify-token
Server-to-server validation. Pass your secret key and the token from the form.
Request
bash
# GET
curl "https://your-instance.com/api/verify-token?secret=dIZAAAAA...&response=TOKEN"
# or POST (form-encoded or JSON)
curl -X POST https://your-instance.com/api/verify-token \
-d "secret=dIZAAAAA..." -d "response=TOKEN"| Parameter | Required | Description |
|---|---|---|
secret | Yes | Your secret key (server-side only). |
response | Yes | The token submitted by the form. |
Responses
token valid & verified
{ "success": true, "score": 0.87, "risk_level": "low" }token valid but scored as bot
{ "success": false, "score": 0.12, "risk_level": "high" }problems
{ "success": false, "error": "Invalid token" } // expired or unknown
{ "success": false, "error": "Invalid secret key" } // wrong/Inactive site
{ "success": false, "error": "Missing parameters" } // 400Rate limits
| Scope | Limit | Response |
|---|---|---|
| Per IP address | 30 generate-token / minute | 429 + Retry-After |
| Per site key | 60 generate-token / minute | 429 + Retry-After |
Multi-instance deployments
The default limiter is in-memory (per server process). Behind multiple instances, front it with an nginx
limit_req zone or swap in a Redis-backed counter.CORS
generate-tokenreflects the caller'sOriginand allows credentials — required because the widget is embedded cross-origin.api.jsandverify-tokenare open (*) — verify-token is meant to be called server-side, where CORS doesn't apply anyway.
Scores explained: AI Scoring Engine.