Developer Resources
Integrations & SDKs
Add fraud detection to any stack in under 5 minutes. Works with any language that can make HTTP requests — no proprietary SDK required.
< 40ms
Average global response time
Any lang
REST API works with any HTTP client
No SDK
Plain HTTP POST, zero dependencies
API Reference
One endpoint. Full signal set.
A single POST request returns a risk score, verdict, and all detection signals. No pagination, no setup, no webhooks required to get started.
Endpoint
Method
POST
URL
https://api.sntlhq.com/v1/check
Auth
Authorization: Bearer YOUR_API_KEY
Request
{ "ip": "1.2.3.4", "user_agent": "...", "headers": {} }
Response
{ "risk_score": 94, "verdict": "block", "signals": { "vpn": true, "proxy": false, "tor": false, "datacenter": false, "residential_proxy": true, "headless": false }, "country": "US", "latency_ms": 28 }
Code Examples
Pick your language
Copy-paste ready examples for the most common server-side languages. All examples show the full request/response flow with a block-or-pass pattern.
Node.js / JavaScript
const response = await fetch('https://api.sntlhq.com/v1/check', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
ip: req.ip,
user_agent: req.headers['user-agent'],
headers: req.headers
})
});
const result = await response.json();
if (result.verdict === 'block') {
return res.status(403).json({ error: 'Access denied' });
}
Python
import requests
response = requests.post(
'https://api.sntlhq.com/v1/check',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'ip': request.remote_addr,
'user_agent': request.headers.get('User-Agent'),
'headers': dict(request.headers)
}
)
result = response.json()
if result['verdict'] == 'block':
return jsonify({'error': 'Access denied'}), 403
PHP
$response = file_get_contents('https://api.sntlhq.com/v1/check', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Authorization: Bearer YOUR_API_KEY\r\nContent-Type: application/json\r\n",
'content' => json_encode([
'ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'headers' => getallheaders()
])
]
]));
$result = json_decode($response, true);
if ($result['verdict'] === 'block') {
http_response_code(403);
echo json_encode(['error' => 'Access denied']);
exit;
}
Go
type CheckRequest struct {
IP string `json:"ip"`
UserAgent string `json:"user_agent"`
Headers map[string]string `json:"headers"`
}
func checkIP(ip, userAgent string) (*SentinelResult, error) {
body, _ := json.Marshal(CheckRequest{IP: ip, UserAgent: userAgent})
req, _ := http.NewRequest("POST", "https://api.sntlhq.com/v1/check", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { return nil, err }
defer resp.Body.Close()
var result SentinelResult
json.NewDecoder(resp.Body).Decode(&result)
return &result, nil
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.sntlhq.com/v1/check')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request['Authorization'] = 'Bearer YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {
ip: request.remote_ip,
user_agent: request.user_agent,
headers: request.headers.to_h
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
render json: { error: 'Access denied' }, status: 403 if result['verdict'] == 'block'
Java
HttpClient client = HttpClient.newHttpClient();
String body = String.format(
"{\"ip\":\"%s\",\"user_agent\":\"%s\"}",
request.getRemoteAddr(),
request.getHeader("User-Agent")
);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create("https://api.sntlhq.com/v1/check"))
.header("Authorization", "Bearer YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(httpRequest,
HttpResponse.BodyHandlers.ofString());
JSONObject result = new JSONObject(response.body());
if ("block".equals(result.getString("verdict"))) {
response.setStatus(403);
return Map.of("error", "Access denied");
}
Compatibility
Works with every framework
If your framework can make an outbound HTTP request, Sentinel works. No middleware, no plugins, no vendor lock-in.
Next.js
Node / React
Express.js
Node
Fastify
Node
NestJS
Node / TS
Django
Python
FastAPI
Python
Flask
Python
Laravel
PHP
Symfony
PHP
Rails
Ruby
Spring Boot
Java
Gin
Go
Echo
Go
Get your free API key
10,000 requests/month free. No credit card required. Up and running in under 5 minutes.