Skip to main content

Sentinel — real-time fraud, VPN, proxy, and bot detection API. Free tier, sub-40ms response.

Project description

Sentinel Python SDK

Real-time fraud, VPN, proxy, and bot detection — free tier, sub-40ms global response.

Zero dependencies. Just the standard library.

Install

pip install sentinelsup

Quick start

import os
from sentinel import Sentinel

s = Sentinel(api_key=os.environ["SENTINEL_API_KEY"])

result = s.evaluate(token=request.json["sentinelToken"])

if result.is_suspicious:
    return abort(403, "Sentinel flagged this session")

print(result.decision)        # 'allow' | 'review' | 'block'
print(result.risk_score)      # 0..100
print(result.network)         # {'vpn': True, 'proxy': False, 'datacenter': True, ...}
print(result.reasons)         # ['ip_in_known_vpn_range', 'datacenter_asn', ...]

Get your API key

Sign up at sntlhq.com/signup — free, no credit card.

Flask example — block VPN/proxy signups

from flask import Flask, request, abort, jsonify
from sentinel import Sentinel, SentinelError

app = Flask(__name__)
sentinel = Sentinel()  # reads SENTINEL_API_KEY from env

@app.route("/signup", methods=["POST"])
def signup():
    data = request.get_json()
    try:
        result = sentinel.evaluate(token=data["sentinelToken"])
    except SentinelError as e:
        # Fail open OR fail closed — your call. Logged either way.
        app.logger.warning("Sentinel error: %s", e)
        result = None

    if result and result.is_blocked:
        abort(403, "Signup blocked")

    # ... your normal signup flow
    return jsonify({"ok": True})

Django example — middleware for high-value endpoints

from django.http import JsonResponse
from sentinel import Sentinel

sentinel = Sentinel()  # reads SENTINEL_API_KEY from env

class FraudCheckMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.path.startswith("/api/checkout"):
            token = request.META.get("HTTP_X_SENTINEL_TOKEN")
            if token:
                try:
                    result = sentinel.evaluate(token=token)
                    if result.is_blocked:
                        return JsonResponse({"error": "blocked"}, status=403)
                except Exception:
                    pass  # fail open
        return self.get_response(request)

Configuration

Sentinel(
    api_key="sk_live_...",          # required (or via SENTINEL_API_KEY env var)
    endpoint="https://sntlhq.com",  # override for testing
    timeout=5.0,                    # seconds
)

Response shape

@dataclass
class EvaluateResult:
    decision: str | None        # 'allow' | 'review' | 'block'
    risk_score: int | None      # 0..100
    ip: str | None
    country: str | None         # ISO-2
    asn: str | None             # 'AS16509'
    asn_org: str | None         # 'Amazon.com, Inc.'
    network: dict               # {vpn, proxy, datacenter, anonymous, residential}
    device: dict                # {headless, automation, fingerprint_age_days}
    reasons: list[str]
    raw: dict                   # full upstream response

    is_suspicious: bool         # True if decision != 'allow'
    is_blocked: bool            # True if decision == 'block'

Errors

All failures raise SentinelError. The exception carries .status (HTTP code) and .body (parsed error body) when available.

from sentinel import Sentinel, SentinelError

try:
    result = sentinel.evaluate(token=tok)
except SentinelError as e:
    if e.status == 429:
        # back off
        pass
    elif e.status and 400 <= e.status < 500:
        # bad input, won't recover by retrying
        pass
    else:
        # transient — retry once or fail open
        pass

Try the API without signing up

curl https://sntlhq.com/v1/evaluate/sample?scenario=vpn

Or use the interactive playground.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentinelsup-0.1.0.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sentinelsup-0.1.0-py3-none-any.whl (5.6 kB view details)

Uploaded Python 3

File details

Details for the file sentinelsup-0.1.0.tar.gz.

File metadata

  • Download URL: sentinelsup-0.1.0.tar.gz
  • Upload date:
  • Size: 6.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for sentinelsup-0.1.0.tar.gz
Algorithm Hash digest
SHA256 74ddc9fd4b9ed8c1b1db133c8609e980fc833efe34c779d385af0d96199504ce
MD5 63ebda88efd9d2dcff3638970cd9977a
BLAKE2b-256 b7e475ad32b957d70fefe5a4b22b664a74855830a779564a1ae0fe61ff70fe64

See more details on using hashes here.

File details

Details for the file sentinelsup-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sentinelsup-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for sentinelsup-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bba499554f3a93499aa1b7fc4662707144b40318b8c94556b28bd8dcc98748d3
MD5 13cee2afec1991239870ea12b5238972
BLAKE2b-256 774e7787d8833fd12bf996dbd0775766b5fa55938c83bb90be9cdfa24ebb76cc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page