When there's no free tier: gate the whole route, not a single tool.
- Gate POST /threads/{id}/runs/wait with the payments-py ASGI PaymentMiddleware
- Keep POST /threads and discovery endpoints free; protect only the run
- Return 402 + the x402 envelope, then 200 + the settlement receipt on retry
- Deploy the graph to hosted LangSmith Deployment with langgraph up
The middleware follows the canonical x402 lifecycle: verify → agent runs → settle, and only settles if the agent succeeded. Failed runs don't bill the buyer; settlement failures after a successful run are logged but never surface to the client — the buyer already got the value.
Use this pattern when every message is paid. For a free-introspection concierge, use the in-tool gating of the research agent instead.
POST /threads → free
POST /threads/{id}/runs/wait → PAID (402 → 200 + receipt)
GET /assistants/search, /info, /ok → pass through| src/nvm_app.py | four lines of glue that wrap the app with PaymentMiddleware |
| src/buyer.py | drives the 402 round-trip and prints the settlement receipt |
Sandbox agent — real payment round-trips (402 → authorize → settle) with a per-session credit balance, no external service and no real money. The runs/wait route is gated by route-level ASGI middleware; the sandbox runs the 402 round-trip locally. See the README to call a hosted LangSmith deployment.