Detect fleet and fuel card misuse at the pump

Grayson checks a fleet card's fuel authorization against the truck's telematics, its fill history and the station, separates cloned cards and fuel theft from routine fills, and picks approve, alert, decline or block.

Grayson checks a fleet card's fuel authorization against where the assigned truck is, how much room its tanks have, the card's recent fills and what you know about the station. It returns how likely the fill is misuse, whether it looks like a routine fill, the driver's personal use, fuel theft for resale, or a cloned or stolen card, whether the assigned unit is at the pump, and whether to approve, approve and alert the fleet manager, decline, or block the card. It costs about $0.35 to $0.43 per 1,000 decisions.

  • Decides: Tell routine fills from cloned cards, fuel theft and personal use, and choose approve, alert the fleet, decline or block.
  • Call it: When a fleet card authorizes fuel at a truck stop or fuel station
  • Questions: 1 score, 2 choice, 1 yes/no
  • Cost: $0.00035 to $0.00043 per decision ($0.35 to $0.43 per 1,000) for these examples' 10,003 to 12,151 input tokens
  • Latency: 191 to 198 ms for these examples, the median of 5 calls each through api.finic.ai from US-West

Examples

Three diesel authorizations on driver and vehicle cards, each sent with 90 days of the card's fills (with the engine fuel level before and after each one), the truck's daily telematics, its pings around the swipe, the card's controls and what the provider knows about the station. They are a skimmed card fueling in Texas while its truck sits in Ohio, a reefer truck's tractor fill on a new lane with a new driver, and a second fill on a driver's card minutes after his own truck was filled, with a nearly empty fleet truck parked next to him.

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.

  • action is the recommendation. Block the card when block_card leads, and send approve_and_alert_manager to the fleet's exception queue so the manager confirms or disputes it the same day.
  • pattern routes follow-up: a cloned card goes to your compromise team to find the skimmed station and the other cards used there, and driver personal use or fuel theft goes to the fleet, which handles its own drivers.
  • assigned_unit_at_station answers the first question an analyst asks. When it's no and the truck's telematics is reporting, few fills are legitimate.

Call it from your code

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

Fleet card controls check the card: a valid driver ID, an allowed product, a gallon limit. A skimmer at the pump captures the driver ID along with the card, and a driver filling a second vehicle stays inside every limit. What gives misuse away is the truck: where it is at the swipe, how full its tanks are, and whether the gallons pumped match the change in its fuel level. Rules on those signals fire on reefer fills, new lanes and odometer typos, so fleet managers learn to ignore them.

What to send

Send the authorization with the card's history and the truck's telematics. The examples send 28 to 49 transactions and 90 days of daily telematics each, in about 10,000 to 12,000 input tokens.

  • The unit's position, ignition and duty status at the swipe. A truck parked 1,200 miles away with its engine off rules out the assigned unit.
  • Engine fuel level before and after each fill. Gallons pumped that don't show up in the tank went somewhere else.
  • The card's fills, with prompts and products. Odometer entries, pumps, reefer and DEF fills and declined merchandise show the driver's routine.
  • Who the card belongs to. The driver and unit assignment, recent driver changes and the fleet's other units nearby.
  • The card's controls and alerts. Product and gallon limits, rules that fired and how the fleet answered earlier alerts.
  • The station. Skimmer reports, compromised-card lists and tonight's activity across your cards.

Add your own policy

Fleets differ on whether a driver may fuel another of their trucks, so put the fleet's policy in the request and Grayson applies it. This one is a fleet's rule that drivers never fuel another unit on their card, and that a second diesel fill into a truck that's already full is declined without blocking the card.

The fleet's cross-fueling rule adds this to the state of the ambiguous example:

{
  "fleet_fuel_policy": "Redbank Ridge Transport fuel policy, filed with us 2026-09-30 and applying to all its cards: A driver's card is only for the unit it is assigned to. Drivers may not fuel another unit, even one of ours; when a unit has no working card, dispatch calls your help desk for a one-time fuel code. Decline, but do not block, any second diesel authorization on a card within 2 hours when that card's unit has already filled to over 90% and is still at the station, and text our fleet manager. The driver can call dispatch, and we will request a code if the fill is for one of our units."
}
QuestionWithoutWith the fleet's cross-fueling rule
misuse_likelihood2.14 of 4, confidence 29% (Very unlikely 34%, Unlikely 12%, Uncertain 3%, Likely 8%, Very likely 43%)3.10 of 4, confidence 54% (Very unlikely 11%, Unlikely 9%, Uncertain 3%, Likely 14%, Very likely 63%)
patternlegitimate, confidence 48%legitimate, confidence 42%
assigned_unit_at_station99% trueOver 99% true
actionblock_card, confidence 21%decline, confidence 82%

In the ambiguous example, the driver's truck is already at 99% and a fleet truck without a working card is parked next to him. Without the rule, Grayson's action is split between blocking the card, declining and approving with an alert. Under the fleet's rule the second fill is declined and dispatch requests a one-time fuel code, so the action moves to declining with the card left active, while the other answers barely change.

Where to call it

  • At authorization, before the pump is released, when your telematics integration can return the unit's position and fuel level in time.
  • After the fill completes, when the pumped gallons and the new fuel level are known, to alert the fleet or block the card before the next swipe.
  • On compromise reports, for every card used at a skimmed station, to find the ones already being used somewhere else.

Cost and latency

ExampleInput tokensPer decisionPer 1,000 decisionsLatency
Obvious11,667$0.00041$0.41195 ms
Legitimate12,151$0.00043$0.43198 ms
Ambiguous10,003$0.00035$0.35191 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/fleet-fuel-card-misuse/questions.json --label misuse_likelihood=<column> --label pattern=<column> --label assigned_unit_at_station=<column> --label action=<column>

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

  • misuse_likelihood: a level, such as "Very likely (over 90%)"
  • pattern: legitimate, driver_personal_use, fuel_theft_or_resale, cloned_or_skimmed_card, stolen_card
  • assigned_unit_at_station: true or false
  • action: approve, approve_and_alert_manager, decline, block_card

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

What if a fleet doesn't share telematics with us?

Send what you have. The card's own history still shows fills too large for the truck's tanks, fills too close together, odometer entries that don't add up and stations far from the fleet's usual lanes, and the station's compromise reports still apply. Without the unit's position and fuel level, expect more of the probability to sit between legitimate and the misuse patterns, and route more cases to approve_and_alert_manager.

Can it catch a driver who pumps a little extra on every fill?

Yes, if the state shows it. Send the pumped gallons and the engine fuel level change for each fill, as the examples do: a driver who skims 20 gallons a fill shows a steady gap that sensor error doesn't explain, while one large unexplained fill stands out on its own. Fuel-level senders read in whole percent and tanks equalize slowly, so expect a few gallons of difference on honest fills.

Who decides what happens to the driver?

The fleet. Grayson recommends what to do with the authorization and the card; driver personal use and fuel theft go to the fleet manager with the evidence, and the fleet decides about its own driver.

On this page