Juicer Fraud Detection
Every Juicer session is evaluated against six independent fraud vectors. A single failed vector doesn't usually ban a Juicer — but the platform tracks a running fraud score per Juicer, and crossing thresholds triggers automatic action.
Target outcome: fewer than 3% fraud incidents in the pilot city.
The Six Vectors
| # | Vector | What It Catches |
|---|---|---|
| 1 | GPS drift at pickup | Juicer not actually at the vehicle when they claim pickup |
| 2 | Photo timestamp drift | Juicer waited too long between claim and pickup, or photo was taken in a different session |
| 3 | Drop-zone polygon | Juicer dropped the vehicle outside any allowed drop zone |
| 4 | Charge duration plausibility | Juicer claims an SoC delta that's impossible given the elapsed time |
| 5 | Photo hash collision | Juicer is reusing a previous photo (theirs or someone else's) |
| 6 | Radius violation | Juicer is operating outside their verified home radius |
Each vector emits one of three signals — clean, warn, or block. Warns add to the fraud score; blocks reject the action and also add to the score.
Vector 1: GPS Drift at Pickup
Pickup photo GPS is compared to the vehicle's last telemetry GPS.
| Drift | Signal | Fraud-Score Delta |
|---|---|---|
| ≤50 m | clean | 0 |
| 50–200 m | warn | +5 |
| >200 m | block | +10 |
The 50 m threshold accounts for GPS jitter on the phone and the vehicle's IoT module. The 200 m threshold catches Juicers attempting to claim from a parking lot away from the actual vehicle.
If the vehicle hasn't reported telemetry in the last 30 minutes, the platform falls back to the bounty's stored vehicle location and logs a "stale telemetry" note — the pickup still proceeds.
Vector 2: Photo Timestamp Drift
The pickup photo carries an EXIF timestamp. The platform compares it to the claim timestamp.
| Drift | Signal | Fraud-Score Delta |
|---|---|---|
| ≤5 min | clean | 0 |
| 5–30 min | warn | +3 |
| >30 min | block | +5 |
A drift past 30 minutes usually means the Juicer claimed, didn't actually pick up immediately, and then took a photo later (or pulled an old photo from their library). Most genuine pickups complete within 5 minutes.
EXIF metadata is stripped from the stored copy of the photo after the timestamp is read — we keep the timestamp on the session row, not the EXIF block, so we don't accidentally leak location data on shared images.
Vector 3: Drop-Zone Polygon
The drop photo's GPS is checked against the operator's active drop zones via PostGIS ST_Contains. There's no fuzz margin — the drop is either inside an active zone or it isn't.
| Result | Signal | Fraud-Score Delta |
|---|---|---|
| Inside zone | clean | 0 |
| Outside zone | block | +10 |
The Juicer cannot complete the bounty until the drop is inside a zone. They can move the vehicle and try again — there's no penalty for a retried attempt, only for the failed one.
Drop zones are a subset of the operator's existing zone catalog — operators mark specific zones as Juicer-eligible. See Drop Zones in the zones docs for managing zone polygons.
Vector 4: Charge Duration Plausibility
The platform tracks pickup_soc, the latest reported SoC during charge-checkins, and the elapsed time. The required minimum is 0.6 minutes per percent of SoC delta — anything faster is physically impossible on a standard wall charger and triggers a block.
Example: A pack picked up at 12% SoC reported at 95% SoC needs at least (95 - 12) × 0.6 = 49.8 minutes of elapsed charge time. If the Juicer reports 95% after only 18 minutes, the drop is blocked and flagged for manual review.
| Elapsed vs. Expected | Signal | Fraud-Score Delta |
|---|---|---|
| ≥0.6 min/% | clean | 0 |
| 0.3–0.6 min/% | warn | +5 |
| <0.3 min/% | block | +15 |
The 0.6 threshold is intentionally generous — fast chargers exist, and pack chemistry varies. The point is to catch "I just made up an SoC number" cases, not to police charge speed.
Vector 5: Photo Hash Collision
Every pickup and drop photo is hashed (perceptual hash, not bitwise). Each session's photo hashes are compared against:
- The same Juicer's prior session photos
- All other Juicers' photos in the same subaccount (last 90 days)
| Result | Signal | Fraud-Score Delta |
|---|---|---|
| No collision | clean | 0 |
| Soft collision (similar but not identical) | warn | +5 |
| Hard collision (identical hash) | block | +20 |
A hard collision usually means a Juicer is reusing a single photo across multiple pickups, or sharing photos with a friend who's also a Juicer. Both are explicit fraud.
The +20 demerit is the largest single hit because the intent is unambiguous.
Vector 6: Radius Violation
The Juicer's home address (set at onboarding) creates a home_geo PostGIS point. Every claim is checked against the Juicer's configured claim_radius_m (default 8047 m ≈ 5 mi, configurable per subaccount).
| Result | Signal | Fraud-Score Delta |
|---|---|---|
| Within radius | clean | 0 |
| Outside radius | block | +5 |
A Juicer in TX can't claim a vehicle in FL. They can't operate while traveling out of state, period. The point is to keep KYC ground-truth meaningful — the verified address has to be where they actually work.
If a Juicer moves, they can request a home_geo update from the dashboard; operators approve the change manually after a quick review.
Fraud Score Thresholds
Each Juicer carries a running fraud_score on their row. The lifetime score is accumulated as warnings and blocks fire.
| Score | Action |
|---|---|
| 0 – 24 | Normal — no action |
| 25 – 49 | Warning displayed on operator dashboard |
| 50 – 99 | Auto-suspend — Juicer cannot claim until operator reviews |
| 100+ | Auto-ban — status = 'banned', all queued payouts held |
The auto-suspend at 50 and auto-ban at 100 are platform defaults; operators can change them per subaccount.
Scores do not decay automatically. Operators can manually reduce a Juicer's score from the dashboard with a reason note — used when an isolated false-positive is clearly explainable (e.g., GPS jitter near a tunnel).
Manual Operator Tools
In addition to the automatic system, operators can:
- Hold a payout — pause a queued payout pending investigation
- Reverse a payout — claw back a paid payout (via Stripe reversal)
- Cancel a session — end a session early without paying
- Suspend / ban — instantly lock a Juicer out
- Add to ban list — a banned Juicer's
auth.users.idis recorded; new applications from the same identity are rejected
All actions are logged on the Juicer's detail page with the operator who took them and the timestamp.
What the Juicer Sees
When a check fails, the Juicer gets a specific message:
- "Pickup location is too far from the vehicle. Move closer and try again."
- "Drop is outside an allowed zone. Move the vehicle into a drop zone."
- "Charge duration is too short — please check in regularly while charging."
- "Photo appears identical to a previous photo. Please take a fresh photo of the vehicle."
When fraud-score thresholds trigger, they see a "Your account is under review" banner with the operator's contact info.
Common Fraud Patterns the System Has Caught
- The phantom Juicer — claims, never picks up, hopes the TTL doesn't reset. Caught by the no-show counter and the 3-point demerit per expired claim.
- The photo recycler — reuses one good pickup photo across many claims. Caught by hash collision (+20).
- The teleporter — claims a vehicle, photos a different one a block away. Caught by GPS drift (+10).
- The instant charger — claims at 15%, drops at 95% in 12 minutes. Caught by charge plausibility (+15).
- The out-of-state operator — claims a vehicle in a city they don't live in. Caught by radius violation (+5).
- The duplicate identity — same name and SSN-last-4 from a different email. Caught by Stripe Identity dedup at KYC.