Tollstile

Charge per detection with SAM 3

Outcome pricing for a segmentation API — SAM 3 proposes every instance, a second opinion checks each crop, and only the detections that survive are charged for.

Public Beta · early access

"Find every solar panel in this aerial image."

Nobody knows what that costs until it runs. There may be forty panels or none, and the caller cannot be quoted a price in advance without one side taking the risk: a flat fee overcharges the empty image, and per-megapixel billing charges the same for both.

This is the shape upTo() exists for — and detection has a second problem text work does not. The model that produces the results also scores them. A segmentation model returns a confidence or a predicted IoU for every mask it emits; billing per detection on the seller's own confidence is billing on the seller's own word.

The pattern

Authorize a ceiling, run the detector, have something else look at the image, and settle only the detections that survive.

app.post('/detect', tollstile(toll.price(upTo('$0.20'))), async (c) => {
  const { image, target } = await c.req.json();
  const found = await detect(image, target);          // your model
  const kept = await verify(image, target, found);    // a second opinion
  const payment = c.get('payment');

  if (kept.length === 0) {
    // Nothing survived: a 4xx releases the hold, and the caller keeps the authorization.
    return c.json({ found: 0, verified: 0, charged: '$0.00' }, 422);
  }

  await payment.fulfill({ amount: price(kept.length) });
  return c.json({ detections: kept, pricing: explain(kept, found) });
});

price(n) is yours: a cent a detection, a sliding scale, a floor that covers the GPU time. The point is not the formula — it is that n is the number of results someone other than the detector was willing to stand behind.

The second opinion

A verifier answers one typed question per detection: is this region the thing that was asked for? A System One model fits, because the answer wanted is a calibrated probability rather than prose, and because the questions are independent — a hundred crops are a hundred parallel questions, not a hundred conversations.

Three rules carry over from text, and they matter more here:

  • Uncertainty is not a detection. A crop the verifier is unsure about does not get charged for. With a probability rather than a label, this is a threshold you can move and publish, not a hunch.
  • Nothing found is free. The empty image is the case a flat fee gets wrong, and the one a caller remembers.
  • The receipt shows the arithmetic. How many the detector proposed, how many survived, at what threshold, judged by which model and version. A count nobody can check is a count nobody trusts.

Video is the sharper case. Tracking a subject through thirty minutes of footage has a cost the seller cannot predict either — shots vary, the subject leaves frame — and "settle per verified shot, under a ceiling the caller approved" is a price both sides can reason about before anyone commits.

When not to do this

When your cost is the product. GPU seconds are measurable after the fact and perfectly honest to bill for. If you are selling compute, meter compute; a verifier adds latency and a dependency to a price you can already justify.

When the verifier is weaker than the detector. Verifying a mask is harder than verifying a sentence. If your second opinion is less reliable than the model it checks, you have added an expensive source of billing errors, and every false negative is money you do not charge for work you did do. Measure both against labelled examples before either of them touches an invoice.

When the buyer cannot dispute. Outcome pricing is only fair if the disagreement has somewhere to go. Keep the detections, the crops and the verdicts long enough to argue about, and refund on the rails that support it.

Run on a real photograph

Measured on 20 September 2026 — a suburban intersection with three cars in it, SAM 3 through fal, a vision model describing each crop, and Jev deciding:

Three cars in a street photograph, each boxed, each labelled with SAM's score, Jev's probability and the cent it was charged; a banner reads authorized $0.20, charged $0.03

The boxes are SAM 3's. The first number on each is SAM's own confidence, the second is the judge's, and the cent is what the buyer paid for that one. A number plate has been blurred; nothing else is retouched.

"find every car" (1024×768)
  fal-ai/sam-3 proposed 3 in 2067 ms
    ✓ 138,580 347×114   proposer 0.97  judge 0.99  "A gray sedan parked on the street."
    ✓ 437,555 229×89    proposer 0.97  judge 0.98  "A dark gray SUV parked beside another car."
    ✓ 311,564 125×34    proposer 0.93  judge 0.96  "A white vehicle partially obscured by a gray car."
  authorized $0.20 · charged $0.03

"find every bicycle" — proposed 0 in 1353 ms · charged $0.00

Three things that run teaches, and none of them were obvious beforehand:

SAM 3 labels now. Earlier versions were class-agnostic — you clicked, and got a mask with no idea what it was. SAM 3 takes a noun phrase, returns every instance of it, and scores each one itself. So the self-marking problem does not disappear with a segmentation model; it arrives with one.

A vision model will not give you a number. Ask it to state a confidence and it is guessing at its own certainty; ask for logprobs and this gateway returns an empty list, for text as much as for images. What works is two stages: the vision model says what the crop shows, and a System One model says whether that sentence is the concept — with a probability, from a model built to produce them. Neither of the two chose the crop.

Whether that second stage earns its place is a measurable question, so here it is measured — seven crops of the photograph above, the three cars plus a wheel, a traffic light, a palm tree and bare road:

croptruthvision model, yes/nodescribe → Jevdescribe → general LLM
grey sedancaryes ✓0.99 ✓1.00 ✓
dark SUVcaryes ✓0.98 ✓1.00 ✓
white car, half hiddencaryes ✓0.98 ✓1.00 ✓
front wheel onlynot a caryes ✗0.85 ✗1.00 ✗
traffic lightnot a carno ✓0.02 ✓0.00 ✓
palm treenot a carno ✓0.01 ✓0.00 ✓
empty roadnot a carno ✓0.03 ✓0.00 ✓
6 / 76 / 76 / 7

Equal on accuracy, and all three wrong about the same thing: a crop of a wheel, described as "a car wheel and part of the vehicle's body". They are not equal on what you can do about it. Only the judge is unsure — 0.85, against a confident yes from the other two — and the real cars sit at 0.98 and above, so a threshold of 0.9 fixes that case and costs nothing. A yes/no has no such knob.

Seven crops of one photograph is an anecdote, not a benchmark. The point is the shape of the argument: if your price is graded, your judge has to be.

The rate limit is the cost, not the tokens. Three crops took 38 seconds, because that gateway team allows five vision calls a minute. The judging itself is cents and milliseconds.

A worked example

examples/detection-pricing runs the whole thing on a drawn scene — four solar panels, two skylights that look exactly like panels, and a pool:

"find a solar panel" — authorized $0.20
  detector proposed 6, verifier kept 4 at p ≥ 0.7
    ✓ 40,48 56×34          detector 0.99  verifier 0.90
    · 210,60 34×28         detector 0.96  verifier 0.15   ← a skylight
    ✓ 300,196 64×38        detector 0.99  verifier 0.90
  charged $0.04 · 16 ms

The detector is sure about the skylights: 0.96. Per-detection billing on the detector's own confidence charges for six. The verifier's opinion charges for four.

Its model verifier asks a vision model one yes/no question per crop with max_tokens: 1 and logprobs: true, and takes the probability from the distribution over that single token. A model that writes "confidence": 0.95 is guessing at its own certainty; a token probability is measured.

What is verified here

The payment path is tested and live: a ceiling authorized before the work, a second opinion deciding the amount, fulfill() settling it, and a 4xx releasing the hold when nothing survives — the same path as examples/jev-pricing, which runs on the live demo. The run above is real, with the rule-based verifier.

What is not measured here is the thing that decides whether this is fair on your images: how often a real verifier agrees with a person, and what it costs per image. The example's model path is exercised against a stubbed gateway, not against aerial photography. Measure it before you charge anyone, and publish what you measured — a pricing scheme whose accuracy nobody has checked is one nobody should adopt.

See also

On this page