In Part 3, we set amount to "0" — a membership gate that checks you've deposited but doesn't charge. Now change it to "10":
"acl:condition": {
"@type": "PaymentCondition",
"amount": "10",
"currency": "tbtc4"
}
That's it. Every read now costs 10 sats. The server deducts from the reader's balance automatically. When the balance hits zero, the reader gets 402 again until they top up.
Using the same setup from Part 3 (JSS running with --pay, Alice's pod, premium article), update the ACL:
curl -X PUT http://localhost:4443/alice/public/premium.json.acl \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/ld+json" \
-d '[
{
"@context": {"acl": "http://www.w3.org/ns/auth/acl#"},
"@id": "#owner",
"@type": "acl:Authorization",
"acl:agent": {"@id": "http://localhost:4443/alice/profile/card#me"},
"acl:accessTo": {"@id": "http://localhost:4443/alice/public/premium.json"},
"acl:mode": [{"@id": "acl:Read"}, {"@id": "acl:Write"}, {"@id": "acl:Control"}]
},
{
"@context": {"acl": "http://www.w3.org/ns/auth/acl#"},
"@id": "#paid",
"@type": "acl:Authorization",
"acl:agentClass": {"@id": "acl:AuthenticatedAgent"},
"acl:accessTo": {"@id": "http://localhost:4443/alice/public/premium.json"},
"acl:mode": [{"@id": "acl:Read"}],
"acl:condition": {
"@type": "PaymentCondition",
"amount": "10",
"currency": "tbtc4"
}
}
]'
Say you deposited 50 sats in Part 3. Now read the article five times:
Read 6:
{
"type": "PaymentRequired",
"amount": "10",
"currency": "tbtc4"
}
Out of sats. Deposit more to continue reading.
On each successful paid request, the server includes headers so the client can track spending:
HTTP/1.1 200 OK X-Cost: 10 X-Balance: 30 Content-Type: application/ld+json
A smart client can display a balance meter, warn when funds are low, or prompt for a top-up — all from standard HTTP headers. No proprietary API. No JavaScript SDK. Just headers.
Different resources can have different prices. Each one is just an ACL:
| Resource | Amount | Use Case |
|---|---|---|
/free/ | No condition | Public content |
/members/ | "0" | Membership gate (Part 3) |
/articles/ | "10" | Blog posts |
/api/data | "1" | Cheap API calls |
/premium/report.pdf | "1000" | High-value content |
Use acl:default to price an entire folder at once, or set per-resource ACLs for individual pricing. The same inheritance model from Part 1.
For the first time, a web server can charge for content using a standard HTTP status code, a standard access control spec, and cryptographic identity. No payment processor. No subscription platform. No cookies tracking what you read. The reader pays sats. The server serves content. The transaction is between two parties, not three.
| Traditional | HTTP 402 | |
|---|---|---|
| Middleman | Stripe, PayPal, app store | None |
| Fee | 2.9% + 30¢ per transaction | 0 |
| Minimum payment | ~50¢ (economics of card fees) | 1 sat (~$0.001) |
| Account required | Email, password, credit card | Nostr key |
| Tracking | Cookies, analytics, profiling | None — key is pseudonymous |
| Chargebacks | Yes | No — sats are final |
| Works offline | No | Balance is local to the pod |
A 10-sat article at today's prices costs about one hundredth of a cent. Try charging that with a credit card.
Part 5: Your Pod Is Your Bank. You deposited sats. You spent sats. Where did the money go? It's a JSON file on your server. Check your balance, read the webledger, understand TXO URIs.