Skip to main content

Installation

pip install xenarch[fastapi]

Prerequisites

  • A Xenarch publisher account
  • A registered site with site token and site ID
  • Your access token secret (from site registration)

Pattern 1: Site-wide middleware

Gates all bot traffic across your application:
from fastapi import FastAPI
from xenarch.middleware import XenarchMiddleware

app = FastAPI()

app.add_middleware(
    XenarchMiddleware,
    site_token="st_...",
    site_id="your-site-uuid",
    access_token_secret="your_secret",
    excluded_paths={"/healthz", "/docs", "/openapi.json"},
)

@app.get("/articles")
async def articles():
    return {"articles": [...]}

Parameters

ParameterTypeRequiredDescription
site_tokenstrYesYour site token (st_...)
site_idstrYesYour site UUID
access_token_secretstrYesSecret for token verification
api_basestrNoPlatform API URL (default: https://xenarch.dev)
excluded_pathsset[str]NoPaths to skip gating

Pattern 2: Per-route decorator

Gates individual routes:
from fastapi import FastAPI, Request
from xenarch.decorator import require_payment

app = FastAPI()

gate = require_payment(
    site_token="st_...",
    site_id="your-site-uuid",
    access_token_secret="your_secret",
)

@app.get("/")
async def home():
    """Free for everyone."""
    return {"message": "Welcome"}

@app.get("/premium")
@gate
async def premium(request: Request):
    """Gated — bots must pay."""
    return {"content": "premium data"}
The decorated function must accept a request: Request parameter.

How it works

Human request     → passes through (zero overhead)
Bot + valid token → passes through
Bot + no token    → HTTP 402 with payment gate
  1. Checks User-Agent against known bot signatures
  2. If bot: checks Authorization: Bearer header for a valid access token
  3. Valid token: verifies HMAC signature, checks expiry, checks site_id — all local, no API call
  4. No token: calls POST /v1/gates to create a gate, returns HTTP 402

Testing

# Human request — passes through
curl http://localhost:8000/articles

# Bot without token — 402
curl -H "User-Agent: GPTBot/1.0" http://localhost:8000/articles

# Bot with token — passes through
curl -H "User-Agent: GPTBot/1.0" \
     -H "Authorization: Bearer eyJ..." \
     http://localhost:8000/articles

Full example

See the FastAPI publisher example for a complete working application.