stile
HTTP API

Risk

Score the fraud risk of an IP, email, phone, or device — standalone, before or alongside a verification session.

The Risk API scores the fraud risk of a set of signals — IP, email, phone, device — and returns a level and a recommended action. Use it to pre-screen a user before starting verification, to gate a high-value action, or to enrich your own fraud model. It's a standalone endpoint: no verification session is required, though you can attach one.

PII is hashed

Identifiers you send (IP, email, phone) are hashed server-side before anything is persisted — the raw values are used only to compute the score for this request.

Score risk

POST/v1/risk/score

At least one identifier — ip, email, phone, or device_id — is required.

ParameterTypeDescription
ipstringThe user's IP address (IPv4 or IPv6).
emailstringThe user's email address.
phonestringThe user's phone number.
device_idstringA device fingerprint or stable device identifier you collected.
user_agentstringThe browser/user-agent string, used for additional signal.
session_idstringOptional verification session (vks_...) to associate. When set, the assessment rolls up into that session's risk view.
claimed_countrystringThe jurisdiction the user claims (ISO 3166, e.g. "US", "US-CA", "DE"). Compared against IP-derived geo.
doc_countrystringISO 3166 alpha-2 country of a document the user presented, when available.
doc_regionstring1–3 character region/state code of a presented document, when available.
required_jurisdictionstringThe jurisdiction your use case requires (ISO 3166). Lets the engine flag a mismatch against the user's signals.
curl https://api.stile.id/v1/risk/score \
  -H "Authorization: Bearer stile_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "ip": "203.0.113.10",
    "email": "user@example.com",
    "claimed_country": "US-CA"
  }'
const res = await fetch("https://api.stile.id/v1/risk/score", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.STILE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    ip: "203.0.113.10",
    email: "user@example.com",
    claimed_country: "US-CA",
  }),
});
const assessment = await res.json();
import requests, os

res = requests.post(
    "https://api.stile.id/v1/risk/score",
    headers={"Authorization": f"Bearer {os.environ['STILE_API_KEY']}"},
    json={"ip": "203.0.113.10", "email": "user@example.com", "claimed_country": "US-CA"},
)
assessment = res.json()

Response

{
  "id": "risk_assessment_abc123",
  "object": "risk_assessment",
  "risk_score": 18,
  "risk_level": "low",
  "recommendation": "allow",
  "triggered_signals": ["geo_mismatch"],
  "reasons": ["Claimed jurisdiction differs from IP-derived location"],
  "signal_details": {},
  "created": 1741564800
}
ParameterTypeDescription
risk_scorenumberThe numeric risk score.
risk_level"low" | "medium" | "high"The bucketed risk level.
recommendation"allow" | "review" | "block"The suggested action — `allow` for low, `review` for medium, `block` for high. Advisory; your application decides.
triggered_signalsstring[]The signal keys that fired for this assessment.
reasonsstring[]Human-readable explanations for the triggered signals.
signal_detailsobjectPer-signal detail used to compute the score.

Retrieve an assessment

GET/v1/risk/:id

Fetch a previously computed assessment by its id.

curl https://api.stile.id/v1/risk/risk_assessment_abc123 \
  -H "Authorization: Bearer stile_sk_..."

Risk runs inside verification too

You don't have to call this API to benefit from risk scoring — supplementary signals (IP analysis, device risk, geolocation) run automatically inside a verification session when your workflow includes them. This endpoint is for scoring outside of, or ahead of, a session.

Next steps

On this page