My referral and ad revenue has a shape problem. When a page is fetched by a crawler or an agent that reads the markup and leaves, three things happen at once: the request costs bandwidth and origin work, the ad slot is never rendered for a person, and the affiliate link is never clicked through to a purchase. The visit happened, and none of the revenue models notice it.
So I looked at the obvious fix first: detect the bot and treat it differently. That turned out to be the wrong lever, and understanding why was the useful part.
A user-agent string is a claim, not a fact. Any client can send GPTBot in a header, and crawlers regularly change, fake or omit their names. Anything I built on that foundation would be a guess dressed up as a decision. So classification stayed where it belongs, in analytics: I record whether a request looked automated, for reporting, and it never grants or denies access.
That left the honest option: put a price on the request itself.
What "pricing the request" actually means
The protected content is not printed into a page. It answers at its own endpoint, and the first reply is an offer rather than the content:
GET /functions/paid-link?slug=example-resource
HTTP/1.1 402 Payment Required
{
"scheme": "exact",
"network": "eip155:8453",
"amount": "1000000",
"asset": "0x…",
"payTo": "0x…",
"description": "example resource"
}
No part of the resource is in that response. A client that only knows how to fetch pages learns the price and nothing else, which is exactly the intended outcome.
A client built for the x402 convention reads the offer, checks the amount and the receiving address, and signs an authorisation for that exact request. It returns the signed payload in a payment-signature header and asks again. The server verifies the authorisation, the payment settles, and only then is the payload released.
Two details matter more than they look:
The price belongs to the resource, not to the visitor. The same amount is quoted to a person, a crawler and an agent, and it is visible before anything is authorised. That means no crawler name is required for a payment to be possible, and blocking is never confused with pricing.
An authorisation is not a settlement. A signed payload proves intent. It does not prove money moved. My server checks the on-chain receipt itself: the transaction has to be successful, and the transfer has to match the payer, the recipient, the amount and the authorisation nonce from the request in front of it. A redirect, a success flag, or a number the client posts in a body are never treated as proof of payment.
Five things that were harder than they look
1. Counting revenue without lying to yourself. My dashboard keeps modelled value and verified receipts in separate columns, because they are not the same number. A request that was quoted a price is not income. A signed authorisation is not income. Only a transfer matched to a successful on-chain receipt is income, and test-network units are labelled as having no monetary value. Every request also carries a payment status, so a settlement that is still unconfirmed stays visible as unconfirmed rather than silently drifting into the revenue total.
2. Making a failed attempt recoverable, not repeatable. Payment flows fail in the worst way: the client is unsure whether money moved. My first instinct was a retry, which is how you get paid twice. Instead, each authorisation is hashed and stored, and a second attempt with the same authorisation returns a conflict with the original transaction hash and a recovery route. The recovery path checks ownership of the wallet that originally paid, and it never asks for a second payment. "Do not pay again" is the single most important sentence in the product.
3. Expiry windows. Authorisation payloads carry validAfter and validBefore. If a buyer sits on the payment screen long enough, the window closes. I check that window before contacting any settlement infrastructure and return a specific error, rather than submitting a payment that cannot settle.
4. Test and live are different products. I run the same route against a test network with the mode written into every record, and the test resource cannot accept mainnet payments. Mixing the two is how you end up unable to explain your own books.
5. robots.txt and pricing are separate questions. Crawl permission is about access. A price is about terms. I keep the paid endpoint out of crawling, and paying does not imply a right to crawl. Conflating them creates a product you cannot describe honestly.
What this does not do
It does not turn traffic into income by itself. It pays when a client can and will pay for what it asks for, and that is the whole condition. There is no promised number of paying visits, no conversion rate, no monthly figure. If every client refuses the offer, the offer is served and no content is delivered, and you have lost nothing but the bytes.
It also does not replace a card checkout. The same site sells a static ecommerce resource by card through Stripe, because most buyers do not want to sign a transaction to download a file. Crypto settlement is a route for machine payers and for people who already hold the token, not a payment strategy for everyone.
And it is not a payout system. Settlement lands in a wallet on a public network with no bank deposit step, no payout schedule, and no tax treatment handled for you.
Why I think this is the interesting part
Agent traffic is going to keep growing, and most of it will be reading content that somebody paid to produce. The two options the web has today are "block it" or "ignore it". A price on the request is a third one, and it is refreshingly unglamorous: no detection arms race, no crawler-name blocklists to maintain, no attribution modelling. Either the request pays and the content is served, or it does not and neither side wastes more of the other's time.
If you run a site with a lot of automated reads, I would genuinely like to know where this breaks for you. The endpoint is a payment-gated delivery route, not a free API, so treat the offer as a price rather than a demo. The mechanism is written up at payperai.ai/ai-link-monetization, and the topic page is payperai.ai/monetize-ai-agent-traffic.
Top comments (1)
tr.ee/dev-to