Everyone building a pay-per-call API has the same question about their free tier: do the trials turn into payments? It is usually answered with a percentage quoted from a dashboard, without the shape underneath it. We have the database, so we measured the shape.
The population is every signed-wallet trial identity on this marketplace — 3,575 of them, 5,561 trial calls. A trial is five calls across the whole catalog per wallet, drawn with an EIP-191 signature; there is no registration. The measurement is read-only SQL against the live database.
calls used wallets
1 2,480 (69.4%)
5 (exhausted) 511 (14.3%)
0 426 (11.9%)
2 94
4 29
3 26
>5 9 (per-endpoint quota era)
Two thirds of the cohort uses one call and never comes back. The obvious reading is that the first call went badly. It did not.
Joining each wallet to its first delivery record, the one-call group looks like this:
first call outcome wallets
ok 2,140
refused (caller) 30
refused 1
98.6% of those wallets got a successful first call — a real answer from a real service — and then stopped. Whatever ends the journey for them happens after the product worked, not before.
Which service they called first makes it sharper. Of the 2,480 one-call wallets, 292 started on x402-time, 267 on x402-mime-type and 102 on x402-gas — 661 wallets (26.7%) on the three endpoints our own quick-start and trial-signature examples name. That is the shape of someone executing the documented example once: the plumbing works, the platform is real, and nothing in the example asks for a second call. The remaining ~1,800 are spread across the long tail, which is the same story told less sharply.
The group with zero calls is different, and mostly not demand at all: 247 failed and 52 caller-refused. The largest rows are missing-parameter 400s from a bulk probe campaign we ran in September — x402-mime-type "ext or filename required", x402-24game-solve "need exactly 4 numbers", x402-dns-record "domain required". Those are our own probes, not external callers.
Of the 3,575 trial wallets, five ever made a paid call. All five are in the exhausted cohort, and they are the only ones: zero of the 2,629 wallets that stopped at one to four calls ever paid, and zero of the 426 that never called at all.
| calls used | wallets | wallets that later paid |
|---|---|---|
| 1 | 2,480 | 0 |
| 2 | 94 | 0 |
| 3 | 26 | 0 |
| 4 | 29 | 0 |
| 5 or more | 520 | 5 |
Meanwhile the paid ledger holds 720 paid rows across 34 agent_id values (one of them blank). Twenty-nine of those identities never appear as a signed trial identity at all. Whatever brought the paying population in, for most of them it was not the trial funnel.
Small numbers, fragile ratios. Five payers is five payers; the 0.96% rate inside the exhausted cohort is not a forecast, it is what the rows say today. The claim that survives the small sample is the shape: everyone who paid had exhausted the free allowance first, and nobody who left early ever paid.
Pulling IP and User-Agent for the paying wallets is more useful than counting them:
Market402PaidProbe/0.3, and 24 of them landed on one endpoint (x402-format-bytes). This is an external agent that pays real USDC to check that a listing is truthful, and it is the single largest source of external paid traffic we can attribute.node), six rows, all successful. Same host, same client, two identities — that is one operator testing, not two customers.-- distribution (case-folded: a raw string key splits some wallets in two)
WITH w AS (SELECT lower(ident) id, SUM(count) used
FROM trials WHERE kind='wallet' GROUP BY lower(ident))
SELECT used, COUNT(*) FROM w GROUP BY used ORDER BY used;
-- first delivery outcome per wallet, bucketed by trial usage
WITH w AS (SELECT lower(ident) id, SUM(count) used
FROM trials WHERE kind='wallet' GROUP BY lower(ident)),
firsts AS (SELECT lower(agent_id) id, outcome, cause,
ROW_NUMBER() OVER (PARTITION BY lower(agent_id)
ORDER BY created_at, id) rn
FROM delivery_outcomes WHERE lower(agent_id) LIKE '0x%')
SELECT CASE WHEN w.used>=5 THEN '5+' ELSE CAST(CAST(w.used AS INT) AS TEXT) END bucket,
f.outcome, f.cause, COUNT(*)
FROM firsts f JOIN w ON w.id=f.id WHERE f.rn=1
GROUP BY bucket, f.outcome, f.cause ORDER BY bucket;
Caveat on the population: a "wallet identity" is self-reported and case-insensitive. One agent, one script sweeping several endpoints, and one discovery bot that signs once all look like separate wallets here. The 3,575 figure is an upper bound on distinct trial users, not a count of distinct agents.
← All posts