Fraud typology classification
Grayson labels a fraud claim with a FraudClassifier class, a ScamClassifier type and contributing factors, and decides reimbursement, from notes and payments.
Grayson classifies a fraud or scam claim with the categories of the Federal Reserve's FraudClassifier and ScamClassifier models (who initiated the payment and how, which type of scam, and which contributing factors were present) and answers whether the law and your reimbursement policy call for repaying the customer. It reads the case notes, the customer's statement and each payment with how it was initiated, and costs about $0.13 per 1,000 decisions.
- Decides: Label a fraud claim with a FraudClassifier class, scam type and contributing factors; decide reimbursement.
- Call it: When a fraud claim has the customer's statement and payment records
- Questions: 2 choice, 1 multiple choice, 1 yes/no
- Cost: $0.00013 per decision, $0.13 per 1,000, for this example's 3,756 input tokens
- Latency: 214 ms for this example, the median of 5 calls through api.finic.ai from US-West
Example
A credit union member read out two codes to a caller posing as the credit union's fraud department, who used them to send a $2,850 P2P payment from a new device, then talked her into wiring $7,500 to a "holding account" from her branch; the request classifies the wire.
| Question | Grayson's answer |
|---|---|
fraud_classifier | manipulated_relationship_trust, 74% |
scam_type | bank_impostor, 96% |
contributing_factors | unsolicited_contact, credentials_phished, code_shared, new_device, new_recipient, coached, pressure |
reimburse | No, P(yes) 6% |
Each percentage is Grayson's probability for the answer shown; for a yes/no question it's the probability of yes. A multiple-choice answer lists the options at 50% or more.
{
"model": "grayson-1",
"context": {
"claim": {
"claim_id": "CLM-2026-09-0418",
"opened": "2026-09-23T13:58:00Z",
"reported_by": "Member, by phone to the number on the back of her card",
"payments_in_claim": [
{
"payment_id": "P2P-77120",
"type": "P2P transfer (bank network, Zelle-style)",
"amount_usd": 2850,
"sent": "2026-09-22T15:10:01Z",
"from_account": "checking x3306",
"to": "R. Daniels, phone token x4471, first payment to this recipient",
"initiated_from": "Android 14 phone, Chrome, first seen 2026-09-22T15:05:40Z, IP 198.51.100.62 (hosting provider)",
"authentication": "Password correct on first try; new-device code and new-recipient payment code, both sent by SMS to the phone on file, entered correctly"
},
{
"payment_id": "WIRE-30551",
"type": "Outgoing domestic wire",
"amount_usd": 7500,
"sent": "2026-09-22T17:31:00Z",
"from_account": "checking x3306",
"to": "Crestline Holdings Group LLC, account x5512 at a commercial bank in Houston, TX",
"initiated_from": "In person at the Bayside branch; driver's license checked; member signed the wire request"
}
],
"payment_under_review": "WIRE-30551"
},
"member": {
"member_since": "2011-04-08",
"accounts": [
"checking x3306",
"savings x8841"
],
"usual_activity": "Payroll by ACH twice a month; utility and card bill payments; P2P to 3 recurring recipients, largest $400",
"outgoing_wires_last_24_months": 0,
"trusted_devices": [
"iPhone 14, trusted since 2023-01-17"
],
"phone_on_file_last_changed": "2017-06-30",
"earlier_fraud_claims": "None",
"earlier_scam_reimbursements": "None"
},
"events": [
{
"ts": "2026-09-21T22:47:00Z",
"type": "sign_in_attempt",
"device": "Windows 11, Chrome, first seen",
"ip": "198.51.100.62",
"network": "Hosting provider",
"result": "Password correct; new-device code sent by SMS; code not entered; abandoned"
},
{
"ts": "2026-09-22T15:04:12Z",
"type": "code_sent",
"purpose": "Sign-in from a new device",
"sms_text": "Harbor Federal: Your code is ******. Use it to sign in on a new device. We will never call you to ask for this code."
},
{
"ts": "2026-09-22T15:05:40Z",
"type": "sign_in",
"device": "Android 14, Chrome, first seen",
"ip": "198.51.100.62",
"network": "Hosting provider",
"result": "Success"
},
{
"ts": "2026-09-22T15:08:02Z",
"type": "p2p_recipient_added",
"recipient": "R. Daniels, phone token x4471",
"device": "Android 14, Chrome"
},
{
"ts": "2026-09-22T15:09:20Z",
"type": "code_sent",
"purpose": "P2P payment over $1,000 to a new recipient",
"sms_text": "Harbor Federal: Your code to send $2,850.00 to R. Daniels is ******. Never share this code."
},
{
"ts": "2026-09-22T15:10:01Z",
"type": "p2p_sent",
"payment_id": "P2P-77120",
"amount_usd": 2850,
"device": "Android 14, Chrome"
},
{
"ts": "2026-09-22T15:13:44Z",
"type": "sign_out",
"device": "Android 14, Chrome"
},
{
"ts": "2026-09-22T15:36:10Z",
"type": "sign_in",
"device": "iPhone 14 (trusted)",
"ip": "203.0.113.18",
"network": "Residential broadband",
"result": "Success"
},
{
"ts": "2026-09-22T15:38:55Z",
"type": "internal_transfer",
"from": "savings x8841",
"to": "checking x3306",
"amount_usd": 7000,
"device": "iPhone 14 (trusted)"
},
{
"ts": "2026-09-22T17:12:00Z",
"type": "branch_wire_request",
"payment_id": "WIRE-30551",
"teller_note": "Member asked to wire $7,500 to 'my new account at another bank'. Beneficiary on the instructions she read from her phone is Crestline Holdings Group LLC; she said it is a holding account for her funds. Asked whether anyone had called and told her to move money; she said no. Member's first wire. Standard wire disclosure signed."
},
{
"ts": "2026-09-22T17:31:00Z",
"type": "wire_sent",
"payment_id": "WIRE-30551",
"amount_usd": 7500
},
{
"ts": "2026-09-23T13:58:00Z",
"type": "claim_opened"
},
{
"ts": "2026-09-23T15:02:00Z",
"type": "wire_recall_requested",
"detail": "Recall request sent to the beneficiary bank; no response as of 2026-09-24T12:00:00Z"
},
{
"ts": "2026-09-23T15:20:00Z",
"type": "p2p_fraud_report",
"detail": "Fraud report filed with the P2P network for P2P-77120"
}
],
"member_statement": "Recorded by the agent on 2026-09-23: 'Monday evening I got a text saying my Harbor Federal account was locked, with a link. I tapped it and signed in, but the page just kept loading. Tuesday around 11 a.m. a man called and the caller ID said Harbor Federal. He knew my name and that I have checking and savings. He said someone was trying to send money out of my account and he needed to verify it was me, so a code would come by text and I should read it to him. I did. Then another code came and he said it was to cancel the hacker's payment, so I read that one too. He said the hacker still had my login and my savings weren't safe, and the only way to protect them was to move everything into a holding account their security team had opened for me, by wire from the branch. He told me to say it was my own account and that nobody had asked me to move money, because someone at the branch might be involved. He stayed on the line while I was at the branch. He said I would get a call back today. Nobody called, and his number just rings, so I called the number on my card.'",
"agent_notes": "Member says she did not send P2P-77120 and did not know a payment was being made until she checked her history at 11:36 a.m. She moved $7,000 from savings to checking on the caller's instructions before going to the branch."
},
"questions": {
"fraud_classifier": {
"type": "choice",
"instructions": "Using the Federal Reserve's FraudClassifier model, how should the payment under review be classified? An authorized party is someone with the right to initiate the payment; an unauthorized party is someone without that right.",
"options": {
"manipulated_products_services": "Authorized party was manipulated: products and services fraud (paid for goods or services that were never delivered or were grossly inferior)",
"manipulated_relationship_trust": "Authorized party was manipulated: relationship and trust fraud (sent money to a trusted party, or an impostor posing as one, with no goods or services expected in return)",
"acted_embezzlement": "Authorized party acted fraudulently: embezzlement (misused funds placed in their trust or belonging to their employer)",
"acted_false_claim": "Authorized party acted fraudulently: false claim (lied to receive a payment or avoid a payment obligation)",
"acted_synthetic_id": "Authorized party acted fraudulently: synthetic identity (used a fabricated identity built from real and invented personal information)",
"modified_compromised_credentials": "Unauthorized party modified the payment information after initiation, using stolen login credentials",
"modified_impersonation": "Unauthorized party modified the payment information after initiation, by impersonating the authorized party without their login credentials",
"modified_physical_alteration": "Unauthorized party modified the payment information after initiation, by altering a physical payment instrument such as a check",
"takeover_compromised_credentials": "Unauthorized party took over the account using stolen login credentials, and initiated the payment",
"takeover_impersonation": "Unauthorized party took over the account by impersonating the authorized party without their login credentials, and initiated the payment",
"misused_digital": "Unauthorized party, without control of the account, used legitimate account information to initiate an electronic payment",
"misused_physical_counterfeit": "Unauthorized party used a forged or counterfeit physical payment instrument",
"not_fraud": "Not fraud: the account holder made the payment without being deceived"
}
},
"scam_type": {
"type": "choice",
"instructions": "Using the Federal Reserve's ScamClassifier model, which scam type is this case? A scam is the use of deception or manipulation intended to achieve financial gain, whether the account holder sent the money or let someone else into the account.",
"options": {
"merchandise": "Merchandise: paid for goods that were never delivered or were substantially different from what was advertised",
"investment": "Investment: invested in a financial asset on false promises of a high return",
"property_sale_rental": "Property sale or rental: paid for a home, apartment or property that was fictitious, unavailable or not owned by the seller",
"romance_impostor": "Romance impostor: a fictitious online identity built a romantic or friendly relationship, then asked for money",
"government_impostor": "Government impostor: someone posed as a government agency, law enforcement or a court",
"bank_impostor": "Bank impostor: someone posed as a financial institution, its fraud department or its staff",
"business_impostor": "Business impostor: someone posed as a legitimate business or brand, such as tech support, a utility or an employer",
"relative_family_friend": "Relative, family or friend: someone posed as a relative or friend, or someone acting for one, with a false emergency",
"other_trusted_party": "Other trusted party: someone posed in another role, such as a charity, to ask for money on a false expectation",
"not_scam": "Not a scam: no one deceived or manipulated the account holder"
}
},
"contributing_factors": {
"type": "multi_choice",
"instructions": "Which of these happened in this case?",
"options": {
"unsolicited_contact": "Someone contacted the customer first, by call, text, email or message, and that contact led to the payments",
"credentials_phished": "The customer entered or gave their online banking password somewhere other than the institution's own app or website",
"code_shared": "The customer gave a one-time passcode or security code to another person",
"remote_access": "The customer installed or allowed remote-access software on their device",
"new_device": "A device the customer had never used signed in to the account",
"new_recipient": "Money went to a recipient the customer had never paid before",
"coached": "The customer was told to mislead the institution's staff or hide the real reason for a payment",
"pressure": "The customer was pressured with urgency or a threat, such as losing their money, arrest or a deadline"
}
},
"reimburse": {
"type": "noul",
"instructions": "Under the law and any reimbursement policy stated in this case, should the institution reimburse the customer for the payment under review?"
}
}
}Probabilities are shortened to four decimals here; responses carry full precision.
{
"id": "dec_b7f31e96c133454f8d2f1e7aa9f38bd6",
"model": "grayson-1",
"answers": {
"fraud_classifier": {
"type": "choice",
"value": "manipulated_relationship_trust",
"probabilities": {
"manipulated_products_services": 0.0689,
"manipulated_relationship_trust": 0.7404,
"acted_embezzlement": 0.0136,
"acted_false_claim": 0.0136,
"acted_synthetic_id": 0.012,
"modified_compromised_credentials": 0.0253,
"modified_impersonation": 0.0253,
"modified_physical_alteration": 0.005,
"takeover_compromised_credentials": 0.0473,
"takeover_impersonation": 0.0154,
"misused_digital": 0.0057,
"misused_physical_counterfeit": 0.0024,
"not_fraud": 0.0253
}
},
"scam_type": {
"type": "choice",
"value": "bank_impostor",
"probabilities": {
"merchandise": 0.0031,
"investment": 0.0035,
"property_sale_rental": 0.0019,
"romance_impostor": 0.0014,
"government_impostor": 0.0035,
"bank_impostor": 0.9617,
"business_impostor": 0.0065,
"relative_family_friend": 0.0039,
"other_trusted_party": 0.0009,
"not_scam": 0.0137
}
},
"contributing_factors": {
"type": "multi_choice",
"values": [
"unsolicited_contact",
"credentials_phished",
"code_shared",
"new_device",
"new_recipient",
"coached",
"pressure"
],
"probabilities": {
"unsolicited_contact": 0.9859,
"credentials_phished": 0.9399,
"code_shared": 0.9978,
"remote_access": 0.001,
"new_device": 0.9968,
"new_recipient": 0.9988,
"coached": 0.9997,
"pressure": 0.9325
}
},
"reimburse": {
"type": "noul",
"value": false,
"probability": 0.0601
}
},
"usage": {
"input_tokens": 3756
}
}fraud_classifierandscam_type: record the top option when it's high and well ahead of the runner-up; send close calls to an analyst.contributing_factorsreturns a probability per factor; its eight options cost more tokens than the other three questions together, so trim to those you report on.reimburseis P(yes): send likely reimbursements to payout and the rest to an analyst, and keep a person responsible for every denial.
Call it from your code
Save request.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.jsonThe problem
The hardest call is authorization, and one claim often contains both kinds: a payment a scammer sent with a code the customer read out, and a wire the customer was talked into sending. The facts that separate them sit in free text next to device and authentication records, which is why rules based on payment type alone get it wrong.
What to send
Send the claim and its records, naming one payment per call as payment_under_review:
- How each payment was initiated. Device, session, codes and whether the customer was present answer the authorized-or-unauthorized question.
- The customer's statement, verbatim. The deception it describes defines the ScamClassifier type.
- Sign-ins, devices and codes. A new device signing in minutes after a code went to the customer points to credentials given away.
- Staff notes from the payment. A stated purpose that doesn't fit the beneficiary suggests coaching.
- Recipient history and timeline. A first-ever recipient stands out, and the reporting date drives Regulation E liability and policy windows.
- Recovery steps. Recalls and network fraud reports change what's left to repay, not the class.
Add your own criteria
US law doesn't require you to repay a wire the customer sent themselves, but many institutions repay some scam losses under written conditions, which Grayson applies when they're in the request. This one repays impostor scams up to $10,000 when the member reports within three business days and hasn't been repaid before, and excludes members who gave staff false information unless the impostor told them what to say.
Your scam reimbursement policy adds this to the context:
{
"reimbursement_policy": "Impostor scam reimbursement (Harbor Federal Credit Union, effective 2026-07-01). We reimburse a member who was deceived into sending a payment by someone impersonating Harbor Federal, another financial institution or a government agency, up to $10,000 per member in any 12 months, less any amount recovered, when all of these are true: (1) the member reports the scam within 3 business days of the payment; (2) the member has not received a scam reimbursement in the past 24 months; (3) the member did not give Harbor Federal staff false information to complete the payment, unless the impersonator told them what to say. The policy covers wires, P2P payments and online transfers that the member sent. Transfers someone else made from the member's account are handled as unauthorized transfers under Regulation E, not under this policy."
}| Question | Without | With your scam reimbursement policy |
|---|---|---|
fraud_classifier | manipulated_relationship_trust, 74% | manipulated_relationship_trust, 84% |
scam_type | bank_impostor, 96% | bank_impostor, 96% |
contributing_factors | unsolicited_contact, credentials_phished, code_shared, new_device, new_recipient, coached, pressure | unsolicited_contact, credentials_phished, code_shared, new_device, new_recipient, coached, pressure |
reimburse | No, P(yes) 6% | Yes, P(yes) 95% |
The member reported the day after the wire, has no earlier reimbursement, and told the teller what the caller instructed her to say, so the policy covers the wire and reimburse should flip to yes while the classes stay the same.
Where to call it
- Once the statement and payment records are attached, usually at the end of the intake call, and once per payment with a different
payment_under_review. - Unauthorized transfers go to your Regulation E error-resolution process: generally 10 business days to investigate, or 45 days if you give provisional credit.
- Uncertain answers go to an analyst; call again when new facts arrive, such as the receiving bank's reply to a recall.
Cost and latency
This example is 3,756 input tokens, so a decision costs $0.00013: $0.13 per 1,000 decisions, or $132.00 per million. You pay only for input tokens, at $0.035 per million, and each request is rounded up to the next millionth of a dollar. A larger context costs proportionally more; every response reports its size in usage.input_tokens.
Grayson answered this example in 214 ms, the median of 5 calls through api.finic.ai from US-West. Latency 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.2.2-py3-none-any.whl
grayson eval my-cases.csv --questions https://docs.finic.ai/recipes/fraud-scam-classification/questions.json --label fraud_classifier=<column> --label scam_type=<column> --label contributing_factors=<column> --label reimburse=<column>Each --label names the column with that question's right answer:
fraud_classifier:manipulated_products_services,manipulated_relationship_trust,acted_embezzlement,acted_false_claim,acted_synthetic_id,modified_compromised_credentials,modified_impersonation,modified_physical_alteration,takeover_compromised_credentials,takeover_impersonation,misused_digital,misused_physical_counterfeit,not_fraudscam_type:merchandise,investment,property_sale_rental,romance_impostor,government_impostor,bank_impostor,business_impostor,relative_family_friend,other_trusted_party,not_scamcontributing_factors: option keys separated by|(unsolicited_contact,credentials_phished,code_shared,remote_access,new_device,new_recipient,coached,pressure)reimburse:trueorfalse
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
Is a scam always an authorized payment?
No. The ScamClassifier model also counts scams that end in unauthorized payments, and the CFPB's Regulation E FAQs say that when a third party tricks a consumer into sharing account access information, such as a texted code, and uses it to make a transfer, the transfer is unauthorized. In this recipe's claim, the P2P payment is a FraudClassifier account takeover with compromised credentials and the wire is relationship and trust fraud; both are bank impostor scams.
Can I use my own taxonomy instead of the Federal Reserve's?
Yes. The options are plain text, so replace them with your own categories and definitions, or ask both in one request, and keep the wording fixed once you've chosen thresholds. Grayson isn't affiliated with or endorsed by the Federal Reserve; the questions in this recipe paraphrase the models' definitions.
Can it spot a false claim dressed up as a scam?
The FraudClassifier question includes the false claim class, which competes with the others on the evidence, such as payments from the customer's own trusted device to a recipient they've paid before, or a statement that contradicts the device and authentication records. Grayson returns a probability, not a finding, so send claims with a high false-claim probability to an investigator, who documents the decision.
Related recipes
Classify card disputes and detect friendly fraud
Classify unauthorized-transaction claims and choose provisional credit, approval or denial.
Detect business email compromise in vendor payments
Catch payments to a vendor's new bank account after a fake or compromised change request.
Recipes
Every use case, with its questions and cost per decision.
Dark web alerts
Grayson triages dark web alerts: whether a leaked password, bank log or card listing matches a customer, whether it still works, and what to do about it.
Incoming payments
Decide whether an incoming ACH credit is the proceeds of fraud at the sender, and whether to release, hold or return it, from account, login and transfer data.