Skip to main content
The account takeover (ATO) detection API monitors login activity per subject and flags suspicious patterns in real time. It tracks failed login velocity in a rolling one-hour window, assigns a risk level based on configurable thresholds, and automatically creates alerts and risk signals when those thresholds are crossed.
ATO detection is part of the Anti-Fraud Identity Firewall. Alerts and risk signals flow into the same pipeline as other fraud signals, so you can query and review them from the Risk & Fraud > Signals console page or the list signals endpoint.

How it works

1

Send login events

Call POST /v1/risk/ato/evaluate each time a login event occurs — failed attempts, repeated failures, new device logins, or successful logins.
2

Velocity tracking

The platform increments (or resets) the failed login counter for the subject in a rolling one-hour window. Successful logins reset the window.
3

Risk level assignment

A risk level is derived from the current failed login count. The response includes the risk level, numeric score, and current counter value.
4

Automatic alerts and signals

When a subject crosses a threshold, the platform creates an alert and ingests a risk signal with signal_type: "ato". You don’t need a separate API call.
5

Review and respond

Query ATO profiles, list alerts, and review signals in the console or via the API to investigate and respond to threats.

Prerequisites

  • An active Truthlocks tenant with an API key
  • Login event data from your authentication system (failed logins, successes, new device events)

Evaluating a login event

Send a POST request to /v1/risk/ato/evaluate with the subject and event details:
curl -X POST https://api.truthlocks.com/v1/risk/ato/evaluate \
  -H "X-API-Key: tl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "subject_id": "user_abc123",
    "event_type": "login.failed",
    "ip_address": "198.51.100.42"
  }'
The response tells you the current risk posture and whether an alert was triggered:
{
  "subject_id": "user_abc123",
  "subject_type": "user",
  "risk_level": "elevated",
  "risk_score": 50,
  "failed_login_count": 5,
  "alert": true,
  "alert_type": "velocity_exceeded",
  "signal_id": "9f3a1c2d-...",
  "event_type": "login.failed"
}

Threshold rules

The platform assigns a risk level based on the number of failed logins within a one-hour rolling window:
Failed logins (1 h window)Risk levelRisk scoreAlert type
0–4normal10
5–9elevated50velocity_exceeded
10–19high70velocity_exceeded
20+critical90credential_stuffing
When a threshold is crossed:
  1. An alert is created in the ATO alerts table
  2. A risk signal is automatically ingested with signal_type: "ato" and the corresponding score
  3. The response includes alert: true, the alert_type, and the signal_id

Event types

Event typeBehavior
login.failedIncrements the failed login counter
login.failed.repeatedIncrements the failed login counter
login.successResets the failed login counter for the subject
login.new_deviceEvaluates the event and records the new device in the profile

Checking a subject’s risk profile

Retrieve the current ATO risk profile for a subject without triggering a new evaluation:
curl https://api.truthlocks.com/v1/risk/ato/profile/user_abc123 \
  -H "X-API-Key: tl_live_..."
The profile includes the current risk level, failed login count, and lists of known IP addresses and devices associated with the subject.

Listing alerts

Query ATO alerts for your tenant, optionally filtered by subject:
curl "https://api.truthlocks.com/v1/risk/ato/alerts?subject_id=user_abc123&limit=10" \
  -H "X-API-Key: tl_live_..."
Each alert includes the subject, alert type, risk level at the time of triggering, and a reference to the auto-ingested risk signal.

Integration patterns

Block or challenge on elevated risk

Use the risk_level from the evaluate response to decide whether to allow, challenge, or block a login:
const result = await evaluateATO(subjectId, "login.failed", ipAddress);

if (result.risk_level === "critical") {
  await lockAccount(subjectId);
  await notifySecurityTeam(result);
} else if (result.risk_level === "high") {
  await requireMFA(subjectId);
} else if (result.risk_level === "elevated") {
  await addCaptchaChallenge(subjectId);
}

Combine with event normalization

ATO evaluation can complement the event normalization pipeline. Use event normalization for broad risk scoring across all identity events, and ATO evaluation for focused account takeover monitoring with threshold-based alerts.

Combine with velocity scoring

ATO detection focuses on login-based account takeover patterns with built-in threshold rules and alert management. Velocity scoring tracks any action type across multiple rolling time windows (1 m, 5 m, 1 h, 24 h) with weighted burst detection. Use both together for layered protection:
  • ATO detection for focused login security — failed login velocity, credential stuffing alerts, subject risk profiles
  • Velocity scoring for general abuse detection — API rate abuse, transaction flooding, registration spam, or any custom action type
Both produce risk signals in the same unified pipeline, so you can query and review all signals from one place.

Monitor via webhooks

Configure a webhook endpoint to receive real-time notifications when ATO alerts are created, so your security team can respond without polling.

What’s next