Skip to main content
ForgeMeshPay-per-Crawl for Go · v0.1.1 · free, open source

Charge AI crawlers in Go, Caddy or Traefik

One Go module with a net/http middleware, a Caddy handler module and a Traefik plugin. Pure-Go keccak so the core loads inside Traefik's interpreter.

Works with: net/http, Caddy module http.handlers.pay_per_crawl, Traefik plugin

Install

go get github.com/forgemeshlabs/[email protected]

Add the gate

net/httpmain.go
package main

import (
	"net/http"

	"github.com/forgemeshlabs/pay-per-crawl-go/middleware"
	"github.com/forgemeshlabs/pay-per-crawl-go/paypercrawl"
)

func main() {
	site := http.FileServer(http.Dir("./public"))
	http.ListenAndServe(":8080", middleware.Handler(paypercrawl.Config{
		PayTo:    "0xYourWalletOnBase",
		PriceUSD: 0.01,
		Mode:     "monitor",
	}, site))
}
Caddy (build with xcaddy, then Caddyfile)Caddyfile
# xcaddy build --with github.com/forgemeshlabs/pay-per-crawl-go/caddy
example.com {
	route {
		pay_per_crawl {
			pay_to 0xYourWalletOnBase
			price_usd 0.01
			mode monitor
		}
		file_server
	}
}
Traefik (plugin catalog, static config)traefik.yml
experimental:
  plugins:
    payPerCrawl:
      moduleName: github.com/forgemeshlabs/pay-per-crawl-go
      version: v0.1.1
# then a middleware in your dynamic config:
# http.middlewares.ppc.plugin.payPerCrawl.payTo: 0xYourWalletOnBase

Turn it on

  1. 1go get the module and wrap your handler, or build Caddy with the module, or add the Traefik plugin.
  2. 2Set PayTo and keep Mode at monitor.
  3. 3Read the OnHit events, then set Mode to gate.

Settings

PayToYour 0x wallet on Base. Required in gate mode.
PriceUSDPer page fetch, default 0.01.
Modegate or monitor.
FacilitatorURL / FacilitatorAuthAny x402 facilitator supporting exact on Base. Default PayAI.
ClassPolicy / BotOverridesfree, paid or block per class and per crawler.
AllowPathsPath prefixes never gated.
TrustedIPHeaderOnly a header your proxy overwrites or appends. Right-most entry used.
MPPSecretLong random string so MPP challenges survive restarts and span instances.
LockImplement paypercrawl.NonceLock over Redis or a database to share the replay lock across instances.

Things to know

  • Without a verifiable IP, or when DNS is down, a search-engine claim is kept rather than charged.
  • The Caddy download page listing is still pending; build with xcaddy for now.
  • Behind Cloudflare, set AI Crawl Control and any "Block AI bots" rule to Allow for the crawlers you want to charge. A crawler blocked at the edge never reaches the gate and never sees the 402.
  • Humans never see a 402. Search engines are verified by reverse DNS; a request that only claims to be Googlebot is charged.
  • Start in monitor mode. It logs every bot with what it would have paid and never blocks. Switch to gate when the numbers make sense.

Proof it settles

Real settlements on Base mainnet through the PayAI facilitator, $0.01 each, October 2026:

Other stacks

WordPressNext.jsVercelCloudflare WorkersNodenginxPythonPHP