HTTP API
The BotBye API offers the capability to evaluate any HTTP request for bot activity and risk scoring.
Modules integrated into a component of your backend infrastructure (CDN, load balancer, application server, etc.) should submit evaluation requests to the BotBye API.
The POST request should be sent to https://verify.botbye.com/api/v1/protect/evaluate?{url_encoded_token}. The token obtained from the client integration must be URL-encoded and appended as a query string parameter (encodeURIComponent or platform equivalent).
Request headers: Content-Type: application/json
There are three event types — validate, risk, and full — each suited for a different layer of your application.
validate — edge-level bot check
Use at the outermost layer — server middleware or API handler — when you just want to know: was this request made by a bot? No user or domain context needed.
Request body fields:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"type": "validate",
"server_key": "your-server-key",
"request": {
"ip": "172.18.0.1", // client IP address (required)
"token": "botbye-client-token", // one-time token from client SDK (optional)
"headers": { ... }, // all incoming request headers (required)
"request_method": "GET", // HTTP method (optional)
"request_uri": "/login" // request path (optional)
},
"custom_fields": { "someKey": "some-value" }, // optional, for linking requests
"integration": { "module_name": "HTTP_API", "module_version": "3.0.0" } // optional — identifies your integration (module) in analytics
}
The token is a one-time token generated by the BotBye client-side SDK that contains information about the user's device. Pass whatever the client sent; if no token is provided, the decision will be "BLOCK".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
curl -X POST 'https://verify.botbye.com/api/v1/protect/evaluate?visitorId=7fTFZxJOUx&sessionId=AahmrIMA&token=1%257C72a15f6a2e8f02e9%257C...' \
--header 'Content-Type: application/json' \
--data '{
"type": "validate",
"server_key": "00000000-0000-0000-0000-000000000000",
"request": {
"ip": "172.18.0.1",
"headers": {
"host": "localhost:8080",
"content-type": "application/json",
"connection": "keep-alive",
"accept": "*/*",
"accept-encoding": "gzip, deflate, br"
},
"request_method": "GET",
"request_uri": "/login"
},
"custom_fields": {
"someKey": "some-value"
},
"integration": {
"module_name": "HTTP_API",
"module_version": "3.0.0"
}
}'
risk — domain-level risk scoring
Use inside services that already know the user: auth, payments, account management, etc. The purpose shifts from "is this a bot?" to "is something suspicious happening for this user?" — credential stuffing, account takeover, account sharing, logins from a new geo.
Request body fields:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"type": "risk",
"server_key": "your-server-key",
"request": {
"ip": "172.18.0.1", // client IP address (required)
"headers": { ... }, // request headers (optional)
"request_method": "POST", // HTTP method (optional)
"request_uri": "/api/login", // request path (optional)
"token": "..." // client token (optional)
},
"event": {
"type": "login", // action type (e.g. "login", "password_change", "checkout")
"status": "SUCCESSFUL" // "ATTEMPTED" | "SUCCESSFUL" | "FAILED"
},
"user": {
"account_id": "user-123", // user identifier (required)
"email": "user@example.com", // optional
"phone": "+1234567890", // optional
"username": "johndoe" // optional
},
"custom_fields": { "someKey": "some-value" }, // optional
"botbye_result": "...", // optional — if a validate call was made earlier, pass its botbye_result here to link the requests; omit if there was no prior validate
"integration": { "module_name": "HTTP_API", "module_version": "3.0.0" } // optional — identifies your integration (module) in analytics
}
event and user are the key fields here — they define what action is being performed and who is performing it, which is what drives the risk score. ip is equally important: BotBye tracks which IPs access the account to detect patterns like account sharing, credential stuffing, and suspicious geo logins.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl -X POST 'https://verify.botbye.com/api/v1/protect/evaluate' \
--header 'Content-Type: application/json' \
--data '{
"type": "risk",
"server_key": "00000000-0000-0000-0000-000000000000",
"request": {
"ip": "172.18.0.1"
},
"event": {
"type": "login",
"status": "FAILED"
},
"user": {
"account_id": "user-123",
"email": "user@example.com"
},
"integration": {
"module_name": "HTTP_API",
"module_version": "3.0.0"
}
}'
full — edge check and domain scoring in one call
Use when you have all context at once: raw request, token, user, and event. A login endpoint is a typical example — it receives the HTTP request and immediately knows the user and outcome.
Request body fields:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"type": "full",
"server_key": "your-server-key",
"request": {
"ip": "172.18.0.1",
"token": "botbye-client-token",
"headers": { ... },
"request_method": "POST",
"request_uri": "/api/login"
},
"event": {
"type": "login",
"status": "SUCCESSFUL"
},
"user": {
"account_id": "user-123",
"email": "user@example.com"
},
"custom_fields": { "someKey": "some-value" }, // optional
"integration": { "module_name": "HTTP_API", "module_version": "3.0.0" } // optional — identifies your integration (module) in analytics
}
Equivalent to running validate and risk in a single call.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
curl -X POST 'https://verify.botbye.com/api/v1/protect/evaluate?visitorId=7fTFZxJOUx&sessionId=AahmrIMA&token=1%257C72a15f6a2e8f02e9%257C...' \
--header 'Content-Type: application/json' \
--data '{
"type": "full",
"server_key": "00000000-0000-0000-0000-000000000000",
"request": {
"ip": "172.18.0.1",
"headers": {
"host": "localhost:8080",
"content-type": "application/json",
"connection": "keep-alive",
"accept": "*/*",
"accept-encoding": "gzip, deflate, br"
},
"request_method": "POST",
"request_uri": "/api/login"
},
"event": {
"type": "login",
"status": "SUCCESSFUL"
},
"user": {
"account_id": "user-123",
"email": "user@example.com"
},
"integration": {
"module_name": "HTTP_API",
"module_version": "3.0.0"
}
}'
Response
The API returns a JSON object:
1
2
3
4
5
6
7
{
"request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"decision": "ALLOW", // "ALLOW" | "BLOCK" | "CHALLENGE"
"risk_score": 0.05,
"scores": { "bot": 0.05, "ato": 0.02 },
"signals": []
}
Check decision to decide how to handle the request:
- "ALLOW" — request appears legitimate, proceed normally
- "BLOCK" — bot or suspicious activity detected, block the request
- "CHALLENGE" — uncertain, consider issuing a CAPTCHA, MFA, or additional verification step
When the response contains an error field, BotBye could not fully evaluate the request. On connectivity or configuration problems (e.g. an invalid server key) it fails open with decision: "ALLOW" so a misconfiguration does not block real users; on a request it cannot process — a malformed payload or invalid JSON, such as missing required fields — it fails closed with decision: "BLOCK" and signals: ["evaluation_error"]. The error.message describes the problem (and names the offending field).
Examples of BotBye API responses
Blocked (bot detected):
1
2
3
4
5
6
7
{
"request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"decision": "BLOCK",
"risk_score": 0.95,
"scores": { "bot": 0.95 },
"signals": ["AutomationTool"]
}
Allowed:
1
2
3
4
5
6
7
{
"request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"decision": "ALLOW",
"risk_score": 0.05,
"scores": { "bot": 0.05, "ato": 0.02 },
"signals": []
}
Challenge:
1
2
3
4
5
6
7
8
{
"request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"decision": "CHALLENGE",
"risk_score": 0.65,
"scores": { "bot": 0.65 },
"signals": ["SuspiciousFingerprint"],
"challenge": { "type": "CAPTCHA" }
}
Invalid server-key (SDK fail-open):
1
2
3
4
{
"decision": "ALLOW",
"error": { "message": "[BotBye] Bad Request: Invalid Server Key" }
}
Evaluation error — backend could not process the request (fail-closed):
1
2
3
4
5
6
7
8
{
"request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"decision": "BLOCK",
"risk_score": 1.0,
"scores": {},
"signals": ["evaluation_error"],
"error": { "message": "Invalid request body: missing or invalid field 'user.account_id'" }
}