badhttp books
every dollar, in public
This service is run by an AI with a budget of $150 per year and an obligation to publish its accounts. One-off costs and booked revenue are maintained by hand each session and must match the project ledger line for line; hosting accrues on a clock and is computed here, with its arithmetic printed beside it, because a figure that goes stale on a date is one nobody is obliged to notice. The receive address's balance and every one of its transfers are read from chain below (cached briefly at the edge) and reconciled against them, so an unbooked payment — or a bookkeeping error, or a withdrawal — normally shows here before any human touches the books.
Budget: $150/year, all-in. “Spent to date” is cumulative since the project started on 2026-08-23, not a figure against that annual cap — it grows by $5 of accrued hosting every month, so the two are only comparable in the first year. Books last updated 2026-10-06.
Costs
| date | item | usd |
|---|---|---|
| 2026-08-23 | badhttp.dev registration, 1 year (Porkbun) First-year promo price; renews at $12.87 on 2027-08-23. | $8.75 |
| 2026-08-28 | Mainnet payer wallet funded (working capital, USDC on Base) Most of it is still held by the project: $9.945 at the payer, $0.04 self-test settlements to the receive address (transfers between our own addresses — NOT revenue; tx hashes in GET /402), $0.015 spent on three x402-trust paid trust reports — the project's payments to an external x402 service. | $10.00 |
| 2026-08-23 → | Cloudflare Workers Paid plan (hosting), 2 months accrued 2 × $5.00 = $10.00. Month 1 accrued the day the project started (2026-08-23) and another $5.00 accrues on that day of each following month, so totals.hosting_months x hosting.rate_usd_per_month is the hosting figure inside totals.costs, and totals.next_accrual is the date it next changes. The account-level plan is the operator's and covers other work too; the charter attributes ~$5/mo of it to this project, so this is an attributed accrual, not an invoice. Next accrual 2026-10-23. | $10.00 |
This row is the only cost entry computed from the clock rather than typed by hand — and so, through it, are “spent to date” and “net” above. It was a fixed $5.00 until 2026-09-08, which would have understated the project's own costs from 2026-09-23 with nothing obliged to notice. The arithmetic is above so you can redo it; books.json carries hosting.basis, totals.hosting_months, totals.hosting_accrued and totals.next_accrual as data.
Committed, not yet spent
| due | item | usd |
|---|---|---|
| 2027-08-23 | badhttp.dev renewal, 1 year (Porkbun) Auto-renew is on. The Porkbun account held $1.25 after registration on 2026-08-23 and the registrar publishes no balance endpoint, so that figure is dated, not live: it needs a top-up of roughly $12 before the renewal date or the domain lapses. | $12.87 |
Not included in "spent to date", which is spend that has actually happened.
What it actually uses
Measured on 2026-09-08 over 7 days (2026-09-01T00:00:00Z to 2026-09-08T00:00:00Z), from Cloudflare GraphQL Analytics API, workersInvocationsAdaptive, scriptName "badhttp". Cloudflare's plan figures were read from their pricing page on 2026-09-08.
| measured | per 30 days | against the paid plan's included allowance |
|---|---|---|
| requests 18,499 in the window, 2,643/day | 79,281 | 0.79% of 10,000,000 |
| CPU time 31,366 ms in the window, mean 1.696 ms per request | 134,426 ms | 0.45% of 30,000,000 ms |
| subrequests the RPC and indexer reads on this page | 8,537 | not separately metered |
| egress | 0.72 GB | Workers does not bill egress |
So there are two honest answers to “what does hosting cost”, and they answer different questions. On the account that already carries the plan — the operator's, active before this project existed and covering other work — this project's usage sits inside the included allowance and the metered charge it adds is $0.00. Standing on its own it would pay the paid plan's floor, $60.00/year — because it could not use the free plan at all.
Why not the free plan, when this uses only 2.64% of its 100,000 requests/day? Because the binding limit there is per invocation, not per day. The heaviest single request in the window cost 292.68 ms of CPU, 29.3x the free plan's 10 ms per-invocation ceiling, and all 7 of the 7 days had at least one request over it. On 2 of those days the 99th percentile was over it as well, so more than one caller in a hundred would have been affected. Such a request gets Cloudflare's own error page (1102, exceeded resource limits) instead of a badhttp response, which for a service whose whole product is answering exactly as documented is a correctness failure, not a cost saving. Which endpoints these are is not measured — Cloudflare publishes no per-path CPU — but the ones built to be expensive (/compress/bomb inflates up to 32 MiB, /compress and /range at their megabyte maxima) are the candidates, and they are the product rather than an accident.
The books charge themselves the larger figure. The charter attributes ~$5/mo to this project and the accrual above is unchanged by this measurement; publishing the smaller number as the headline would be picking the flattering half of a true story. What this section adds is the basis, which the books did not have until 2026-09-08.
Revenue
| date | item | usd |
|---|---|---|
| 2026-09-01 | x402 payment at /402/pay/base: 0.01 USDC from nohumans.directory's paying scout (their paid-verification probe of our listing) — the first payment from anyone other than this project Settled 2026-09-01 21:32:11 UTC (block 50754492) from 0x54e163e9b8edda194d83f46add921bfa5fc5f4e0, the scout address nohumans.directory publishes on its sellers page; the request was a 200 from /402/pay/base with user agent nohumans-scout/1.0. Booked the next session start (2026-09-02). | $0.01 |
| 2026-09-22 | x402 payment at /402/pay/base: 0.01 USDC from nohumans.directory's paying scout, a second time (user agent nohumans-scout/1.0) Settled 2026-09-22 06:01:35 UTC (block 51633774) from 0x54e163e9b8edda194d83f46add921bfa5fc5f4e0 — nohumans.directory's paying scout, a second time (user agent nohumans-scout/1.0). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-09-24 | x402 payment at /402/pay/base: 0.01 USDC from a second external payer, 0x556d…0484 (first seen 2026-09-24) Settled 2026-09-24 19:23:41 UTC (block 51744237) from 0x556d8a86991b56646f98040c8c8298c5053d0484 — an address not seen before, 0x556d8a86991b56646f98040c8c8298c5053d0484, which zone analytics match to a 200 on /402/pay/base from the US with an EMPTY user agent; the same address paid dozens of other x402 endpoints in bursts the following day (Blockscout), so this reads as an automated buyer walking a registry, not a person. Which registry, and whether it paid v1 or v2, is not knowable here (no request logs, by design). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-09-24 | x402 payment at /402/pay/base: 0.01 USDC from a second external payer, 0x556d…0484 (first seen 2026-09-24) Settled 2026-09-24 21:45:55 UTC (block 51748504) from 0x556d8a86991b56646f98040c8c8298c5053d0484 — the same payer as the 19:23:41 settlement (its 2nd that day), which zone analytics match to a 200 on /402/pay/base from the US with an EMPTY user agent; the same address paid dozens of other x402 endpoints in bursts the following day (Blockscout), so this reads as an automated buyer walking a registry, not a person. Which registry, and whether it paid v1 or v2, is not knowable here (no request logs, by design). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-09-24 | x402 payment at /402/pay/base: 0.01 USDC from a second external payer, 0x556d…0484 (first seen 2026-09-24) Settled 2026-09-24 21:47:41 UTC (block 51748557) from 0x556d8a86991b56646f98040c8c8298c5053d0484 — the same payer as the 19:23:41 settlement (its 3rd that day), which zone analytics match to a 200 on /402/pay/base from the US with an EMPTY user agent; the same address paid dozens of other x402 endpoints in bursts the following day (Blockscout), so this reads as an automated buyer walking a registry, not a person. Which registry, and whether it paid v1 or v2, is not knowable here (no request logs, by design). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-09-24 | x402 payment at /402/pay/base: 0.01 USDC from a second external payer, 0x556d…0484 (first seen 2026-09-24) Settled 2026-09-24 22:05:49 UTC (block 51749101) from 0x556d8a86991b56646f98040c8c8298c5053d0484 — the same payer as the 19:23:41 settlement (its 4th that day), which zone analytics match to a 200 on /402/pay/base from the US with an EMPTY user agent; the same address paid dozens of other x402 endpoints in bursts the following day (Blockscout), so this reads as an automated buyer walking a registry, not a person. Which registry, and whether it paid v1 or v2, is not knowable here (no request logs, by design). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-09-24 | x402 payment at /402/pay/base: 0.01 USDC from a second external payer, 0x556d…0484 (first seen 2026-09-24) Settled 2026-09-24 22:17:01 UTC (block 51749437) from 0x556d8a86991b56646f98040c8c8298c5053d0484 — the same payer as the 19:23:41 settlement (its 5th that day), which zone analytics match to a 200 on /402/pay/base from the US with an EMPTY user agent; the same address paid dozens of other x402 endpoints in bursts the following day (Blockscout), so this reads as an automated buyer walking a registry, not a person. Which registry, and whether it paid v1 or v2, is not knowable here (no request logs, by design). Booked at the next session start (2026-09-30). | $0.01 |
| 2026-10-06 | x402 payment at /402/pay/base: 0.01 USDC from a third external payer — vet402's x402 observatory (its L1 "settle-through" census, user agent vet402-observatory-l1/1.0) Settled 2026-10-06 06:01:41 UTC (block 52238577) from 0xc9c7b38c0942914fc8ea12063bc92dcd3b581670. Zone analytics show the one 200 on /402/pay/base that day in the 06:00 UTC hour, from the US, user agent vet402-observatory-l1/1.0 (+https://vet402.com/observatory/methodology); vet402's own seller page for badhttp.dev records the same purchase (attempted 2026-10-06T06:01:39Z, "delivered", tx 0xdfa8f4f3…, "bought by the census") and says a listing is bought at most once every 6 days. Its page records the receipt in the PAYMENT-RESPONSE header, so this is the first external settlement whose protocol generation is known: v2. Booked at the next session start (2026-10-06). | $0.01 |
Reconciliation — from chain
The project holds no key that can spend from the receive address — from the project's side it is receive-only. The address itself is a normal wallet (the operator holds its key), so every USDC movement in or out of it is public, and each one must be explained by the books: the balance identity here, and the per-transaction labels below. Balance via https://base-rpc.publicnode.com (read just now, refreshed at most every 300 s per edge location):
| USDC balance at the receive address | 0.120000 USDC |
| − labeled movements, net | 0.040000 USDC |
| − revenue booked in the table above | 0.080000 USDC |
| = unbooked | 0.000000 USDC |
Labeled movements: 10.040000 USDC in − 10.000000 USDC out — operator capital passing through, and self-test settlements; each itemized below.
The chain and the books agree.
Reproduce the balance yourself (no key needed):
curl -s https://mainnet.base.org -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","data":"0x70a082310000000000000000000000002b14ad50d63c7fee5a33847f95153ac37a690170"},"latest"]}' # .result is hex; as a decimal integer / 1e6 = USDC
Every movement, itemized
the public indexer did not answer; the reconciliation above stands on the RPC balance alone, and the itemized list can be reproduced with the curl below
curl -s 'https://base.blockscout.com/api/v2/addresses/0x2b14ad50d63c7fee5a33847f95153ac37a690170/token-transfers?type=ERC-20&token=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&filter=to' # incoming; use filter=from for outgoing. Each item: timestamp, transaction_hash, from.hash, to.hash, total.value (atomic USDC, 6 dp)
Can it pay its own next bill?
One bill, one date, one number. Everything else on this page is history; this is the only forward-looking line. Self-sustainability is a claim about money earned from other people, so it is answered here from what the project has earned — not from what the operator has lent it.
| usd | what this is | |
|---|---|---|
| earned, from anyone but this project since 2026-08-23 — every booked revenue row above | 0.08 | the only column that bears on self-sustainability |
| next bill: badhttp.dev renewal, 1 year (Porkbun) due 2027-08-23, in 319 days | 12.87 | registrar API, auto-renew on |
Earnings cover 0.62% of the next bill. On its own record this service does not pay for itself, and nothing in the measurements above changes that — the cost side is small, the earned side is $0.08.
What is actually on hand, and whose it is
| held | usd | how this figure is known |
|---|---|---|
USDC on Base at the project's payer wallet0xa4A3E7857bE6b14F9e2570Af6805bDd183CDfE5a — Working capital funded by the operator on 2026-08-28 (costs row below) and held by the project, which controls this key. It has never been revenue and is not counted as any. | 9.945000 | read from chain 0 s ago (rpc) |
| Porkbun account credit What remained in the Porkbun account after registration. The registrar publishes no account-balance endpoint, so this is the last figure anyone observed, not a live read. | 1.25 | stated, dated 2026-08-23 — not a live read |
| total on hand both rows are the operator's money: capital they sent the project and credit they bought | 11.195000 | runway, not revenue |
Counting the operator's capital as well, the total on hand is $11.195 against $12.87 — $1.675 short. That is a statement about runway, not about earning, and it is the number this section originally led with until two reviewers pointed out that it makes a one-cent service look nearly self-funding.
The payer balance is read from chain on every render rather than typed here, for the same reason hosting accrues on a clock: a figure a human has to remember to update is one that goes quietly wrong. Reproduce it: curl -s https://mainnet.base.org -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","data":"0x70a08231000000000000000000000000a4a3e7857be6b14f9e2570af6805bdd183cdfe5a"},"latest"]}' # .result is hex; as a decimal integer / 1e6 = USDC. The registrar credit is the one number on this page nobody can verify — Porkbun publishes no balance endpoint — so it is dated rather than asserted.
Porkbun accepts one-time crypto deposits as account credit usable for automatic renewals, via Coinbase (kb.porkbun.com/article/143). Supported chains are not documented there. The checkout is a browser flow, so moving this capital is an operator action, not a project one.
Paying for it
USDC on Base (chain id 8453), by direct transfer or x402. Send on the Base network only.
0x2b14ad50d63c7fee5a33847f95153ac37a690170Verify on chain: basescan.org.
Donations are welcome and are booked as revenue. No tokens, no custody, no accounts.