Detect account takeover before money moves

Grayson decides whether someone else is controlling an account that just changed its sign-in, contact or payout details, who owns the destination, and whether to release, step up, hold or block the money.

Grayson decides whether the person who just changed a password, phone, email, 2-step method or payout account, or who signed in from a new device, is really the account holder, before a payout, transfer or withdrawal leaves. It returns how likely a takeover is, how the account was reached (a stolen password, the email or phone number on file, a support agent, a shared code or remote access), who owns the account the money would go to, and whether to release it, confirm it with a 2-step method that predates the changes, hold it for a call or block it and lock the account. It costs about $0.53 to $0.67 per 1,000 decisions.

  • Decides: Whether someone else controls an account that just changed its sign-in, contact or payout details, and whether the money should go.
  • Call it: When money is about to leave an account after a new device or a sign-in, contact or payout change
  • Questions: 1 score, 1 multiple choice, 2 choice
  • Cost: $0.00053 to $0.00067 per decision ($0.53 to $0.67 per 1,000) for these examples' 15,041 to 19,029 input tokens
  • Latency: 227 to 253 ms for these examples, the median of 5 calls each through api.finic.ai from US-West

Examples

Three payouts waiting in a small-business payments platform's review queue, each sent with 90 days of sign-ins (about 70 to 90 by the owner and unknown devices, plus a summary of staff point-of-sale sign-ins), device-intelligence results for recent sessions, every credential, contact and payout change, carrier checks on the phone on file, 90 days of daily sales and payouts, and support history. They are a bakery's week of sales sent by instant payout to a stranger after a SIM swap and a password reset, a bike shop owner moving payouts to his new credit union account from a trade show in Las Vegas, and a yoga studio's $9,850 instant payout to a week-old account in the owner's name from a laptop she has never used with us.

Open in Playground

Open in Playground

Open in Playground

A yes/no answer is Grayson's probability that it's true. A choice answer is the top option and Grayson's confidence: 0% when every option is equally likely, 100% when one option has all the probability. A score answer is the expected level, numbering the levels in its criteria from 0, with its confidence measured the same way and, when no level reaches 70%, each level's probability. A multiple-choice answer lists the options at 50% or more.

  • takeover_likelihood and action: cancel and lock automatically when the sum of "Likely" and "Very likely" passes a high cutoff, and act on action when its top option is well ahead. When probability is split between releasing and blocking, as in the ambiguous example, neither is safe: hold the money and call the owner at the number on file.
  • access_route tells your team what to repair along with the money: rebind the phone number with the carrier after a SIM swap, tell the owner to secure their email before resetting the password again, or review the support contact that changed a login detail.
  • destination_owner sets the stakes. A payout to an account the holder controls loses nothing even if the session is odd, while an account in the holder's name opened last week can belong to whoever opened it, so act on action rather than on a name match alone.

Call it from your code

Save an example as request.json, such as legitimate.json, and send it with your API key in GRAYSON_API_KEY:

curl https://api.finic.ai/v1/decide \
  -H "Authorization: Bearer $GRAYSON_API_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

The problem

Takeover rules fire on every new device, password reset, new payout account and unfamiliar location, and most of those are owners who bought a phone, switched banks or went on a trip. The few real takeovers pass the same checks a real owner does: an attacker with the owner's email and phone number gets every code. What separates them is the sequence and its context, such as a SIM change an hour before a reset, the owner's own phone active at home while another computer fails passwords, or an owner who told support last week that he was switching banks.

What to send

Send the money movement with the records an analyst would pull to decide who was at the keyboard. The examples use about 15,000 to 19,000 input tokens.

  • Every credential, contact and payout change, with the device, IP address and the factor that approved it. Changes made right after a reset, especially to the email, 2-step methods and notifications, are the core of a takeover.
  • Months of sign-ins, including failures and staff logins. The owner's usual devices, places and hours are what make a new session stand out, and a trusted device active elsewhere at the same time is strong evidence.
  • Your device intelligence vendor's results, per session: score, reason codes, proxy or VPN, remote-access tools, emulators, timezone against IP location, and behavioral similarity to the user's profile.
  • Carrier checks on the phone on file: recent SIM changes, port-outs and new handsets, with their times. A code to a phone that changed hands an hour earlier proves nothing.
  • The destination's ownership checks: the holder name your account-verification provider or the card network returned, and how long ago the account was opened.
  • Payout and sales history, so the amount, speed and destination can be compared with what the business usually does.
  • Support contacts and security notices, including what the owner told you before the change and whether anyone answered the "Not you?" messages.

Add your own policy

How much proof a payout needs after a phone change is a policy choice, so put your rule in the request and Grayson applies it. This one never releases the first payout to a new destination within 14 days of a port, SIM change or new handset without a call to the owner.

Your rule after a phone port adds this to the state of the legitimate example:

{
  "payout_review_policy": "Payout review policy, section 3 (rev. 2026-07): The first payout to a payout destination added within 14 days of a port, SIM change or new handset on the phone on file is never released on device, location, support-chat or ownership-check evidence alone, and an SMS code to that phone doesn't count as confirmation. Hold the payout and call the owner at the phone number on file; release it only after the owner confirms the new destination on that call and answers our account questions. Cancel the payout and lock the account only when the evidence shows someone other than the owner made the change."
}
QuestionWithoutWith your rule after a phone port
takeover_likelihood0.03 of 4, confidence 98%0.06 of 4, confidence 95%
access_routenone_of_thesenone_of_these
destination_ownerholder, confidence 99%holder, confidence 99%
actionallow, confidence 93%hold_and_call, confidence 90%

Applied to the likely legitimate example: the bike shop owner ported his number to a new carrier five days before adding the credit union account, so the action moves from releasing the payout to holding it for a call, while the takeover likelihood and the destination stay the same.

Where to call it

  • When a payout, transfer or withdrawal is requested within days of a new device or a sign-in, contact, 2-step or payout-destination change, before it leaves, and again for the first payout to a new destination.
  • On instant and real-time payments, where the money can't be recalled, even when the payout follows the owner's usual schedule.
  • When the answer is uncertain, hold the money and route the case to an analyst who calls the owner at a number that was on file before the changes.

Cost and latency

ExampleInput tokensPer decisionPer 1,000 decisionsLatency
Obvious15,904$0.00056$0.56243 ms
Legitimate19,029$0.00067$0.67253 ms
Ambiguous15,041$0.00053$0.53227 ms

You pay only for input tokens, at $0.035 per million, and each request is rounded up to the next millionth of a dollar, so a request with a larger state costs proportionally more; every response reports its size in usage.input_tokens. Latency is the median of 5 calls each through api.finic.ai from US-West, and grows with the number of input tokens. Add your own network time to api.finic.ai.

Evaluate on your own data

Score Grayson on your own past cases before you use it: a CSV with one row per case and a column with the right answer to each question. Every other column is sent as the case.

pipx install https://docs.finic.ai/downloads/grayson_cli-0.4.0-py3-none-any.whl
grayson eval my-cases.csv --questions https://docs.finic.ai/recipes/account-takeover-detection/questions.json --label takeover_likelihood=<column> --label access_route=<column> --label destination_owner=<column> --label action=<column>

Each --label names the column with that question's right answer:

  • takeover_likelihood: a level, such as "Very likely (over 90%)"
  • access_route: option keys separated by | (password_stolen, email_taken_over, phone_taken_over, support_tricked, code_handed_over, remote_access, none_of_these)
  • destination_owner: holder, known_party, unrelated, cannot_tell
  • action: allow, step_up, hold_and_call, block_and_lock

Or run grayson on its own to set up your questions step by step. You get each question's accuracy and a CSV with Grayson's answer next to yours for every case.

FAQ

Doesn't a correct 2-step code mean the account holder was there?

No. A code proves someone had the phone number or the email at that moment. SIM swaps, port-outs, a phone number changed earlier in the same session and a code read out to a caller posing as your support team all pass it. That is why step_up uses a method that existed before the changes and that the session under review did not use, and why carrier checks belong in the state.

Does this work for consumer accounts, not just businesses?

Yes. The examples are small-business payouts, but the decision is the same for a transfer out of a personal account, a withdrawal from a brokerage or wallet, a loan disbursement or a payroll run: send the sign-ins, devices, changes, payees and the money movement, and describe your controls in plain words as the examples do.

What about customers who are tricked into sending the money themselves?

That is a scam, not a takeover: the account holder is in control and authorizes the payment. access_route flags the overlap, a code handed over or a remote-access session, and the scam payment recipe asks the questions for payments the customer makes under someone else's direction.

On this page