Screen card authorizations for fraud in real time

Grayson screens card authorizations for card testing, fallback and card-not-present fraud from recent card activity, and picks approve, step up or decline.

Grayson screens a card authorization against the card's recent activity and the cardholder's usual spending, and returns how likely it is to be fraud, whether the card number was just run through card testing, and whether to approve, step up or decline. It can run in parallel with your existing rules and models as an extra signal, and costs about $0.04 per 1,000 decisions.

  • Decides: Score card authorizations for fraud and choose approve, step up or decline, next to your existing rules.
  • Call it: When a card authorization request arrives
  • Questions: 1 score, 1 yes/no, 1 choice
  • Cost: $0.000041 per decision, $0.04 per 1,000, for this example's 1,165 input tokens
  • Latency: 168 ms for this example, the median of 5 calls through api.finic.ai from US-West

Example

A credit card number passed a $1 test at a charity donation page under a BIN attack, and 21 minutes later shows up in a keyed $749.99 online electronics purchase with no 3-D Secure, no security code and an address mismatch.

Open in PlaygroundEdit and run this request in the Finic portal.
QuestionGrayson's answer
fraud_likelihoodVery likely (over 90%), 82%
card_testedYes, P(yes) 98%
actiondecline, 82%

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.

  • action is the recommendation. Start by combining it with your existing decision, for example stepping up when your rules approve but Grayson favors decline.
  • fraud_likelihood: threshold the sum of "Likely" and "Very likely", with separate cutoffs for card-present, card-not-present and cross-border authorizations.
  • card_tested is about the card: a number that passed a test is compromised even if this purchase is declined, so block and reissue it.

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.json

The problem

Rules check fixed conditions, so they miss a $749.99 purchase that follows failed $1 tests at a charity page when no single threshold is crossed, and they decline a traveling cardholder's first foreign purchase. The difference is in the context: what the card did in the last hour, activity at the same merchant across your cards, and how the cardholder usually pays.

What to send

Send the authorization with the card's recent activity and a summary of the cardholder's usual spending:

  • Recent authorizations, including declines. $0 or $1 tests minutes before a larger purchase are card testing.
  • Activity at the same merchant across your cards. A burst of declines on sequential numbers from one BIN is a BIN attack.
  • How the card was read. A fallback read on a chip card that has never needed one is a classic counterfeit signal.
  • Card-not-present checks. 3-D Secure authentication, especially after a challenge, is strong evidence of the cardholder.
  • Usual pattern and recent locations. These separate impossible travel from a cardholder who is simply traveling.
  • Your existing scores and rule results. Grayson weighs them with the rest of the context.

Add your own criteria

Whether to decline or step up trades fraud losses against false declines, so put your strategy in the request and Grayson applies it. This one gives cardholders enrolled in two-way text alerts a confirmation text instead of a hard decline on card-not-present authorizations under $1,000.

Your step-up policy adds this to the context:

{
  "authorization_strategy": "Card-not-present authorization strategy (rev. 2026-08). 1) Cardholders enrolled in two-way text alerts are never hard-declined on a card-not-present authorization under $1,000 for suspected fraud. Step them up instead: return a decline that asks the cardholder to contact us, and text them at the phone on file. If they reply YES within 15 minutes, approve the merchant's retry. If they reply NO or don't reply, block the card and reissue it. 2) Hard-decline and block without a text only when the amount is $1,000 or more, the card is already blocked, or the cardholder has already reported the card lost or stolen."
}
QuestionWithoutWith your step-up policy
fraud_likelihoodVery likely (over 90%), 82%Very likely (over 90%), 78%
card_testedYes, P(yes) 98%Yes, P(yes) 99%
actiondecline, 82%step_up, 93%

This $749.99 card-not-present authorization belongs to an enrolled cardholder, so the action should move from decline to step-up, while the fraud likelihood and card testing answers stay the same.

Where to call it

  • In parallel, with a timeout: run it alongside your rules and model, and fall back to your existing decision if the answer isn't back.
  • Where it adds the most: card-not-present, fallback, cross-border and first-time-merchant authorizations, or your rules' borderline cases.
  • At 3-D Secure authentication, if you control the risk decision there: a likely-fraud answer becomes a challenge.

Cost and latency

This example is 1,165 input tokens, so a decision costs $0.000041: $0.04 per 1,000 decisions, or $41.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 168 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/card-authorization-fraud/questions.json --label fraud_likelihood=<column> --label card_tested=<column> --label action=<column>

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

  • fraud_likelihood: a level, such as "Very likely (over 90%)"
  • card_tested: true or false
  • action: approve, step_up, decline

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 Grayson fast enough for authorization?

Call Grayson in parallel with your existing checks so its time overlaps with theirs, set a timeout that fits your authorization budget, and use your existing decision when the answer doesn't arrive in time. If the budget is too tight to screen every authorization, call it where it adds the most, such as card-not-present and fallback authorizations, or at 3-D Secure authentication.

Can it detect card testing across many cards, not just one?

Grayson reads one context per request, so compute merchant-level counts in your stream processing (attempts, distinct card numbers, decline rate and reasons, numbers running in sequence on your BIN) and add them to each authorization's context, as in the example. You can also send a merchant's recent authorizations on your cards as the context and ask directly whether the merchant is being used for card testing.

Do AVS and CVV2 matches mean the cardholder is making the purchase?

No. Card details stolen through phishing and checkout-page skimmers usually include the billing address and security code, so these checks tell you most when they fail. 3-D Secure authentication with a challenge to the cardholder's phone or banking app is much stronger evidence, which is why the step-up option uses it.

On this page