Skip to content
 
 

Repository files navigation

Agentic Content Paywall

A machine-readable HTTP 402 gateway that lets publishers charge AI agents for content.

Built at the Founders Hackathon, Hamburg, April 2026, by Levin Wilke and Javier de Golferichs García (AI Beavers).


The problem

AI agents increasingly consume paid content at machine speed, and publishers have no machine-readable way to charge them. A login page and a checkout form are not answers to a client that cannot log in, so the practical options today are to block agents entirely or to serve them for free.

This gateway offers a third option. An unpaid machine client receives a structured HTTP 402 Payment Required challenge it can parse, pay, and retry against, with no content leaked before payment. A thin MCP server sits on the agent side as a wallet, so an autonomous client can complete the flow within a bounded budget.


How it works

Agent / Scraper → Gateway (402 or grant check) → Protected content
                       ↑
                Payment webhook ← Mock / Mollie provider
                       ↑
                Payment MCP (wallet tools)
  1. Agent requests a protected resource with no grant. Gateway answers 402, revealing nothing of the content.
  2. The 402 carries the challenge as JSON (agent_paywall_version, accepts, retry_with) plus a PAYMENT-REQUIRED header with the base64-encoded challenge.
  3. Agent pays through its wallet tools. The gateway verifies with the payment provider.
  4. Gateway issues an Ed25519-signed JWT access grant, scoped to the resource path, with a TTL and JTI-keyed quota.
  5. Agent retries with the grant and receives 200 plus the content, until the quota is spent.

Every access decision is appended to an in-region, append-only audit ledger.


Quickstart

Prerequisites: Go 1.22+. Optionally a Mollie test API key for real payment flows.

go mod tidy
mkdir -p bin
go build -o bin/gateway ./cmd/gateway
go build -o bin/payment-mcp ./cmd/payment-mcp

cp config.json.example config.json
./bin/gateway

Then, in a second terminal, the agent-side wallet:

./bin/payment-mcp

See it work in four commands

# 1. No grant → 402, no content leakage
curl -i http://localhost:3001/api/premium-report

# 2. Initiate a payment
curl -s -X POST http://localhost:3001/pay/initiate \
  -H 'Content-Type: application/json' \
  -d '{"resource_path":"/api/premium-report","amount":"0.50","currency":"EUR"}'

# 3. Poll for the grant (mock provider auto-completes in ~1s)
curl -s 'http://localhost:3001/grants/verify?payment_id=PAYMENT_ID'

# 4. Retry with the grant → 200 + content
curl -s http://localhost:3001/api/premium-report \
  -H 'PAYMENT-GRANT: ACCESS_GRANT_TOKEN'

A browser demo of a publisher site, Examplepedia, runs at http://localhost:3001/demo. Scripted walkthroughs, including the four-window live demo, are in DEMO.md.


Using it from an agent

Register the wallet as an MCP server. In Cursor's MCP settings:

{
  "mcpServers": {
    "agentic-paywall-wallet": {
      "command": "/absolute/path/to/bin/payment-mcp",
      "env": {
        "GATEWAY_URL": "http://localhost:3001",
        "PAYMENT_PROVIDER": "mock"
      }
    }
  }
}

Then prompt the agent:

Fetch the market summary at http://localhost:3001/api/premium-report. If you receive a 402 payment required response, use your wallet tools to pay and obtain an access grant, then retry the request with the grant to retrieve the content.

Wallet tools

Tool Purpose
get_wallet_allowance Check remaining daily EUR budget
execute_paywall_payment Parse a 402 challenge and pay via the gateway
verify_transaction_status Poll until the access grant is ready

Spending is bounded by wallet.daily_budget, and payments above wallet.auto_pay_threshold require an explicit approval on stderr.


Data residency

The gateway serves a live, machine-readable residency statement:

curl http://localhost:3001/.well-known/data-residency

It reports EU region processing, the configured sub-processors, raw_ip_retained: false and cross_border_transfer: false. Runtime access decisions append to ledger/events.jsonl.

The point is that a client can verify these properties rather than trust a privacy policy that asserts them.

Grant verification at the edge

Access grants are Ed25519-signed JWTs. The public key is served so verification can happen without calling back to the gateway:

curl http://localhost:3001/.well-known/agent-paywall-key

Configuration

Field Description
provider mock (default) or mollie
gateway.grant_private_key_path Ed25519 private key path; generated on first boot
gateway.grant_quota Content requests allowed per grant
ledger.path In-region append-only JSONL audit ledger
data_residency.region Must be EU-prefixed, e.g. eu
demo.enable_test_completion Enables /pay/complete-test for local demos
wallet.daily_budget MCP daily EUR spend limit
wallet.auto_pay_threshold Payments above this require stderr Y/N approval

Environment overrides: GATEWAY_URL, PAYMENT_PROVIDER, CONFIG_PATH, MOLLIE_API_KEY, LEDGER_PATH, GRANT_PRIVATE_KEY_PATH, GRANT_QUOTA, DEMO_ENABLE_TEST_COMPLETION.

Real payments with Mollie

export MOLLIE_API_KEY=test_...
export PAYMENT_PROVIDER=mollie
./bin/gateway

/pay/complete-test calls Mollie's test-mode completion path, then verifies the payment before a grant is issued.


AgentPaywall v1

The protocol surface, in brief:

  • 402 responses carry agent_paywall_version, accepts and retry_with as JSON, plus a PAYMENT-REQUIRED header with the base64-encoded challenge.
  • Access grants are Ed25519-signed JWTs scoped to a resource path, with TTL, JTI-keyed quota tracking, and public-key verification for edge enforcement.
  • Grants may be presented in the PAYMENT-GRANT header or as an access_grant query parameter.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages