惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
V
V2EX
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
小众软件
小众软件
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
The Cloudflare Blog
T
Tailwind CSS Blog
H
Help Net Security
腾讯CDC
爱范儿
爱范儿
人人都是产品经理
人人都是产品经理
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
Microsoft Security Blog
Microsoft Security Blog
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
C
Check Point Blog
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
The billing state most APIs get wrong: "unknown" is not "no"
Larry Johnson · 2026-06-14 · via DEV Community

Larry Johnson

If you bill per result, there is one design decision that quietly decides whether customers trust you: what you do when you could not get an answer.

Most usage-billed APIs collapse the world into two states. The call worked, or it failed. Valid or invalid. Found or not found. That binary is where the trust leaks out, because it hides a third state that happens constantly in the real world: you asked, and the system genuinely could not tell you right now.

A concrete example

Say you run an email verification endpoint. A customer sends an address, you check it, you bill for the answer. Easy.

Then a DNS lookup times out. Or the domain returns SERVFAIL. Or the mail server greylists your probe and hangs. What do you return?

The lazy answer is invalid, because it is not valid, and now the row is "done" and billable. That single shortcut does two bad things at once. It deletes a real lead from your customer's list, because a timeout is not proof the address is dead. And it charges them for the deletion. They paid you to damage their own data.

The honest version keeps three states:

valid        -> we confirmed it. billable.
invalid      -> we confirmed it is not deliverable (no MX, etc). billable.
unknown      -> we could not determine it right now. NOT billable.

unknown is the whole game. It says "you asked, we tried, we could not be sure, so we are not going to charge you or pretend." It is the difference between a tool that cleans a list and a tool that silently corrupts it.

This generalizes past email

The same gap shows up anywhere you bill per result:

  • A scraper hits a page that 404s. Is that "no contact found" (a real answer) or "we could not load the page" (an unknown)? Bill the first, never the second.
  • A profile lookup gets rate-limited. The lazy path returns an empty profile that looks exactly like a real "this person has no data." Now your customer cannot tell a true empty from a failure, and you billed for both.
  • A price checker can not reach a vendor. Returning "no price" reads as "free or unavailable." Returning unknown reads as "try again." Very different downstream.

The rule I have settled on across a handful of pay-per-event tools: bill for delivered answers, never for attempts, and make "we could not tell" a first-class, free, clearly-labeled output.

Why this is worth the lost revenue

It costs you money on paper. Every unknown and every no-result is a row you did not charge for. Your per-run number looks worse than a competitor who bills for everything including the garbage.

It is also the only version of the number that survives the customer opening their own logs. The competitor who billed for failures looks cheaper for exactly one cycle, until someone notices their bounce rate went up after a "cleaning" or their lead count dropped for no reason. Trust is the actual product. The billing model is just where you prove you have it.

How to implement it without overthinking

  1. Every record carries its own status. Do not infer success from "the batch finished."
  2. Use at least three buckets: answer, no-result, unknown. Add more if your domain needs them (fetch-error, rate-limited, etc), but never fewer.
  3. Only "answer" (and a definitive negative answer, if that is what was asked for) is billable. Everything else is free and labeled.
  4. Say it out loud in your docs. "We do not bill for failed fetches or unknowns" converts better than any feature list, because it tells buyers you understand the failure modes they have already been burned by.

If you are building anything usage-billed, the binary will tempt you because it is simpler and it makes more money this week. Resist it. The third state is cheap insurance against the one outcome you can not recover from, which is a customer deciding your numbers can not be trusted.


I build a few data tools on this rule (the public ones are at apify.com/mrlarryjohnson). Happy to compare notes if you are designing a pay-per-result model. What is your third state?