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

Charge AI crawlers in FastAPI, Flask or Django

One package, three adapters: ASGI for FastAPI and Starlette, WSGI for Flask and anything else, and a Django middleware. Python 3.10+, one dependency.

Works with: FastAPI, Starlette, Flask, any WSGI app, Django

Install

pip install forgemesh-pay-per-crawl

Add the gate

FastAPI / Starlette
from forgemesh_pay_per_crawl import Config
from forgemesh_pay_per_crawl.asgi import PayPerCrawlMiddleware

app.add_middleware(PayPerCrawlMiddleware,
    config=Config(pay_to="0xYourWalletOnBase", mode="gate", price_usd=0.01, base_url="https://example.com"))
Flask (and any WSGI app)
from forgemesh_pay_per_crawl import Config
from forgemesh_pay_per_crawl.wsgi import PayPerCrawlWSGI

app.wsgi_app = PayPerCrawlWSGI(app.wsgi_app,
    Config(pay_to="0xYourWalletOnBase", mode="gate", price_usd=0.01, base_url="https://example.com"))
Django settings.pysettings.py
MIDDLEWARE = ["forgemesh_pay_per_crawl.django.PayPerCrawlMiddleware", *MIDDLEWARE]  # near the top
PAY_PER_CRAWL = {"pay_to": "0xYourWalletOnBase", "mode": "gate", "price_usd": 0.01, "base_url": "https://example.com"}

Turn it on

  1. 1pip install the package and add the adapter for your framework.
  2. 2Start with mode="monitor" and pass base_url if you are behind a proxy.
  3. 3Read the on_event callback or your logs for a day, then switch to mode="gate".

Settings

pay_toYour 0x wallet on Base. Required in gate mode.
mode"monitor" (default) records only; "gate" answers 402.
price_usdPrice per page fetch, default 0.01, minimum 0.005.
facilitator_urlAny x402 facilitator that settles on Base. Default PayAI, no key.
class_policy / bot_overridesPer class and per crawler: "free", "paid" or "block".
allow_pathsPath prefixes never gated. robots.txt, sitemaps, llms.txt, agents.txt and /.well-known/ always are.
base_urlYour public origin. Set it behind a proxy or load balancer.
trust_proxy_headerHeader with the real client IP ("CF-Connecting-IP", "X-Forwarded-For"). Right-most entry used.
mpp_secretStable HMAC key for MPP challenge ids. Set it when you run more than one worker.

Things to know

  • With several worker processes, pass lock=FileNonceLock("/var/tmp/fmppc") so a payment cannot be replayed on another worker, and set a stable mpp_secret.
  • Gate.handle is blocking because it can call the facilitator. In async code run it in a thread, as the ASGI middleware does.
  • 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 WorkersNodenginxGoPHP