Skip to content

Fraud and abuse

Every Customer account carries a risk score built from its signals; past a line, a person reviews it while restrictions hold only the risky part.

A Customer account under risk

Filled: a state someone outside the run sees. Hollow: a private state, a step inside the run.

What raises the score

A risk signal never refuses a call by itself.

Each one feeds the account's score, from 0 to 1, recomputed on each signal and kept with its reasons.

SignalWhat raises it
Card testingMany small declined charges from one account, device or network, and Stripe's checks on each card
Free-call farmingMany sign-ups sharing a card, a device, a network or an email pattern, each taking the free calls or the trial
A leaked KeyOne found in public code, or one Key used from several countries within minutes
Scraping past a licenceCalls that walk every key in order, past what the licence terms allow
Refunds and disputesRefunds or disputes above the product's own rate, or a dispute on every charge
A taken accountSign-in from a new device and country, then a changed email, payout or Key
A runaway agentAn agent's spend far past its own history, even inside its mandate
Stripe's scoreThe risk score Stripe returns on each charge, read as one signal among the rest

Three accounts, three outcomes

The score decides who looks, and a person decides what is blocked. Compare how three accounts go.

An honest Customer, one odd signalA card testerA taken account
What happensA new country raises the score past risk.review; it waits in a queue on the Operator planeMany small declines push it past risk.restrict; restriction holds the risky part at onceA changed payout after a new-device sign-in sends it to review, and a person restricts it
What keeps servingEverythingCalls inside the account's usual spendCalls inside the usual spend, while new Keys and payout changes wait
What answers 403 account_restrictedNothingNew Keys, new purchases, raised ceilings and calls past the usual spendThe same
What it is askedAt most, to confirm its cardTo confirm its card at the verify linkTo confirm its identity
How it endsA person clears it, within a dayVerified, and clear again, or blocked by a personVerified by its owner, and clear again

A block is only ever a person's decision: every Key revoked, each charge refunded by the published rule, the account's records kept. Each restriction and block sends a statement of reasons and an appeal, which a second person decides.

The lines you set

You write where review and restriction start; the file's brakes still cap calls and spend per Customer, whatever its score.

Example

The Dataset API gives one free allowance per card, reviews an account at 0.6 and restricts it at 0.85.

definition.ts
23 lines
import { define, secret } from 'apis.dev'

/** Any company by its domain, with its headcount and sector, free to try once per card. */
export default define({
  name: 'companyfacts', domain: 'companyfacts.apis.dev',
  sources: {
    firms: { origin: 'https://firms.example.com', key: secret('FIRMS_KEY') },
  },
  Company: {
    domain:    { type: 'url!#',   from: 'firms', map: 'website' },
    employees: { type: 'number?', from: 'firms', map: 'headcount' },
    sector:    { type: 'string?', from: 'firms', map: 'industry' },
  },
  offer: {
    'Company.get': 0.002, 'Company.search': 0.005,
    free: { 'Company.get': 100 },
    credits: [10, 50, { pay: 200, get: 220 }],
  },
  operate: {
    brakes: { 'Company.search': { day: 5000 } },               // per Customer, whatever its score
    risk: { trials: 'card', review: 0.6, restrict: 0.85 },     // one free allowance per card
  },
})

A restricted account buying a new credit pack is asked to confirm its card, and its usual lookups keep running. A buyer's agent gets the same 403 and hands its verify link to its person.

Response
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
X-Cost: price=0, currency="USD"
X-Request-Id: req_2f9b06d4c8e1a7357b0d

{
  "type": "https://companyfacts.apis.dev/docs/errors#account_restricted",
  "title": "Forbidden",
  "status": 403,
  "detail": "Under review: new purchases wait until the card is confirmed.",
  "code": "account_restricted",
  "instance": "/checkout",
  "verify": "https://companyfacts.apis.dev/dashboard/verify"
}

One free allowance, and one queue

risk.trials grants one free trial or free-call allowance per card, per org or per sign-up.

Your team works one queue of reviews, each with the signals and calls behind its score, and every decision is kept. A review is open, then cleared, restricted or blocked, by RiskReview.clear or RiskReview.block. An appeal is filed, then granted or denied.