Detect fraudulent incoming ACH credits and transfers

Decide whether an incoming ACH credit is the proceeds of fraud at the sender, and whether to release, hold or return it, from the account's history, the ACH entry and what happened after it posted.

Grayson tells a receiving bank or fintech whether an incoming ACH credit or transfer is likely the proceeds of fraud at the sender, how likely its own customer is acting as a money mule, and whether to release the funds, hold them while it contacts the sending bank, or return the credit. It reads months of the account's activity, its logins and profile changes, the ACH entry and its originator's history with you, and what happened after it posted, and costs about $0.47 to $0.76 per 1,000 decisions.

  • Decides: Release, hold or return an incoming credit that may be proceeds of BEC, account takeover or payroll diversion.
  • Call it: When a large or out-of-pattern incoming ACH credit or transfer posts
  • Questions: 1 yes/no, 1 score, 1 choice
  • Cost: $0.00047 to $0.00076 per decision ($0.47 to $0.76 per 1,000) for these examples' 13,566 to 21,788 input tokens
  • Latency: 192 to 312 ms for these examples, the median of 5 calls each through api.finic.ai from US-West

Examples

Three large corporate credits to personal checking accounts, each sent with five months of transactions, about two months of online-banking events and everything since the credit posted: a payment meant for a timber supplier that lands with a laid-off worker recruited into a "payments" job, a tile contractor's payment from a builder that has paid him for two years, and a new LLC's first big invoice paid into its owner's personal account.

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.

  • proceeds_of_fraud: above your threshold, delay availability of the funds; Nacha's funds-availability exception requires you to notify the sending bank promptly when you use it.
  • mule_likelihood: route a high sum of "Likely" and "Very likely" to your mule-account team, separately from the decision about this credit.
  • action: when return and hold_and_contact are close, hold and restrict outbound transfers; a hold can be released, but a return can't be taken back.

Call it from your code

Save an example as request.json, such as fraud.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

The receiving institution sees only an ACH credit with a company name, an entry description and a receiver name, not the compromise that produced it. Once the funds move on, they are rarely recovered. Simple rules separate the cases poorly: name mismatches are common on legitimate credits, and a large-credit threshold flags every insurance settlement and tax refund.

What to send

Send what your operations team would see on the account and the credit, cut at the moment you decide:

  • The name on the entry and the account's owners. A company or another person's name on a consumer account suggests the sender was misled, unless it's a trade name you have on file.
  • What kind of credit it is. A corporate SEC code or vendor-payment description on a personal account that never received one.
  • Months of the account's activity. Payroll, bills and spending show the account's normal; a credit far above anything before it, or to a dormant account, is out of pattern.
  • The originator's history. Whether this company has paid this account or your other customers before, and under which receiver names.
  • Access and profile changes before the credit. New devices, contact changes and linked accounts show an account being prepared or taken over.
  • What happened after it posted. Money leaving within hours is the strongest sign of a mule account.
  • What the customer and the sending bank said. Messages, call notes and any call or request from the sending bank. A customer forwarding a "client's" payment to "their supplier" is describing a mule arrangement.

Add your own policy

When to return rather than hold is a business decision the data alone can't settle: some institutions always hold and call the sending bank first, while others return on the spot when the evidence is strong. This one returns, the same day, a large corporate credit to a consumer account with an unexplained name mismatch while money is already moving to new payees.

Your return policy for name mismatches adds this to the state of the obvious example:

{
  "institution_policy": "ACH-14, name mismatches on incoming credits. We post ACH credits by account number, but we do not hold a CCD or CTX credit over $10,000 to a consumer account for a call to the sending bank when all three of these are true: (1) the receiver name in the entry matches no owner of the account; (2) we have no business relationship on file between the member and the originator or the named receiver; (3) money has started leaving the account, or a transfer is pending, to a payee or external account added in the last 14 days. In that case, return the full credit the same banking day with return reason R17 and QUESTIONABLE in the addenda, block outbound transfers, and refer the member to BSA. Holding the funds and contacting the sending bank is for mismatches that do not meet all three conditions."
}
QuestionWithoutWith your return policy for name mismatches
proceeds_of_fraud98% true98% true
mule_likelihood3.92 of 4, confidence 95%3.91 of 4, confidence 94%
actionhold_and_contact, confidence 82%return, confidence 96%

All three conditions hold in the obvious-fraud example (the receiver name matches no owner, nothing on file ties the member to the originator or the named receiver, and money is going to a P2P payee added that morning and a crypto exchange account linked 13 days earlier), so the action moves from holding the funds to returning the credit. The other two examples don't meet the conditions: the contractor's trade name is on file, and the new LLC is named in its owner's business account application.

Where to call it

  • When the credit posts, for credits your screening routes for review, before the funds become available.
  • Again when money starts to leave an account holding a recent large credit, with the outbound activity added.
  • When the answer is uncertain, hold the funds and call the sending bank, which can ask its own customer whether the payment was intended.

Cost and latency

ExampleInput tokensPer decisionPer 1,000 decisionsLatency
Obvious13,566$0.00047$0.47192 ms
Legitimate21,788$0.00076$0.76238 ms
Ambiguous15,766$0.00055$0.55312 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/incoming-payment-fraud/questions.json --label proceeds_of_fraud=<column> --label mule_likelihood=<column> --label action=<column>

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

  • proceeds_of_fraud: true or false
  • mule_likelihood: a level, such as "Very likely (over 90%)"
  • action: release, hold_and_contact, return

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

Should I hold or return a credit I think is fraudulent?

Nacha rules allow either: since October 2024, a receiving bank that reasonably suspects a credit is unauthorized or induced by false pretenses may delay its availability (notifying the sending bank promptly) and may return it with R17 and QUESTIONABLE in the addenda. Many teams hold and contact the sending bank first, because a return can't be undone. Whichever you choose, restrict outbound transfers at once: a return is for the full amount, so you fund whatever has already left.

Can Grayson tell an unwitting mule from a complicit one?

The mule_likelihood question covers both on purpose, because the decision about the credit is the same either way. To separate them, add a question such as "Does the account holder appear to be the victim of a job, romance or investment scam that is using their account?" and include the customer's messages and call notes. Intent often becomes clear only after someone talks to the customer, so ask again with the call notes added.

What if the name on the credit matches my customer?

Then the most common giveaway is missing, and the other signals carry the decision: a new or recently reactivated account, a type of credit the account has never received, new devices or profile changes beforehand, and money leaving soon after. Fraudsters also open accounts, including business accounts, in names that match what the sender expects to see.

On this page