Senso
Sign inSign up

Integrations

x402 Payments

Put a per-request paywall in front of your knowledge base so other people's agents can buy verified answers, no account required.

Your knowledge base already answers questions with citations. x402 lets an HTTP endpoint charge for a single request. Put the two together and your compiled knowledge becomes a paid API that any agent can buy from — no signup, no contract, no sales call, settled in the same round trip that served the answer.

This is the mirror image of the OpenAI Agents SDK recipe. There, your agent was the buyer and the discipline was verifying what it got. Here you are the seller, and the discipline is deciding what a verified answer is worth.

What x402 is

x402 revives HTTP's long-unused 402 Payment Required. A client requests a resource, the server answers 402 with machine-readable payment terms, the client signs a stablecoin transfer and retries with proof attached, and the server serves the resource. The whole exchange is three headers.

HeaderDirectionCarries
PAYMENT-REQUIREDServer to client, on the 402Base64 PaymentRequired object with an accepts array
PAYMENT-SIGNATUREClient to server, on the retryThe signed PaymentPayload
PAYMENT-RESPONSEServer to client, on the 200Settlement confirmation
Each entry in accepts names a scheme (usually exact), a network in CAIP-2 form such as eip155:8453, an amount, the payTo address, the asset, and a maxTimeoutSeconds. A facilitator does the chain work on your behalf through two endpoints, /verify and /settle, so your server never holds a private key or watches a block.

The protocol was published by Coinbase in May 2025 and moved to the Linux Foundation's x402 Foundation in 2026. Header names above are v2. If you are reading older material that says X-PAYMENT, that is v1.

The pricing decision this forces

Senso exposes the same vector query at four levels of finish, and each one costs you a different amount to serve. That is a price list waiting to happen.

EndpointWhat the buyer getsCosts you
POST /org/search/contentMatching source IDs and titlesA vector query
POST /org/search/contextRaw chunks, buyer synthesizesA vector query
POST /org/searchA grounded answer, written for themA vector query plus generation
Charging one flat price for all three either overcharges for a lookup or subsidizes someone else's inference. Price the endpoint, not the request. A citation list is worth cents; a written answer carries your generation cost and should say so.

Prerequisites

  • A Senso API key with KB scope (create one on the API Keys page)
  • A receiving wallet address on the network you intend to accept
  • A facilitator URL — https://x402.org/facilitator serves the testnet
  • Python 3.10+
bash
export SENSO_API_KEY="YOUR_SENSO_KEY"
export PAY_TO_ADDRESS="0xYOUR_WALLET"
pip install "x402[fastapi,httpx]" fastapi uvicorn requests

How it works

  1. Agent asks — a GET /answer?q=... arrives with no payment attached
  2. You quote — the server returns 402 and a PAYMENT-REQUIRED header built from the price for that route
  3. Agent pays — it signs a transfer and retries the identical request with PAYMENT-SIGNATURE
  4. Facilitator verifies — your server hands the payload to /verify before doing any work
  5. You serve — only now does the request reach POST /org/search, and the grounded answer goes back with PAYMENT-RESPONSE
  6. You log both halves — the settlement proves they paid, the content_ids prove what they were given

The paid endpoint

python
import os, requests
from fastapi import FastAPI, Request, Response
from x402 import x402ResourceServer, ResourceConfig
from x402.mechanisms.evm.exact import ExactEvmServerScheme
from x402.http import HTTPFacilitatorClient

SENSO = "https://apiv2.senso.ai/api/v1"
HEADERS = {
    "X-API-Key": os.environ["SENSO_API_KEY"],
    "Content-Type": "application/json",
}

facilitator = HTTPFacilitatorClient(url="https://x402.org/facilitator")
server = x402ResourceServer(facilitator)
server.register("eip155:*", ExactEvmServerScheme())
server.initialize()

# One price per level of finish. A citation list is a lookup; a written answer
# carries generation cost, so it is not the same product at a discount.
PRICES = {"/citations": "$0.002", "/context": "$0.01", "/answer": "$0.05"}

def terms(path: str) -> ResourceConfig:
    return ResourceConfig(
        scheme="exact",
        network="eip155:8453",
        pay_to=os.environ["PAY_TO_ADDRESS"],
        price=PRICES[path],
    )

app = FastAPI()

@app.get("/answer")
async def answer(request: Request, q: str):
    signature = request.headers.get("PAYMENT-SIGNATURE")
    requirements = server.build_payment_requirements(terms("/answer"))

    # No proof means quote, do not serve. The 402 body is the price list, and it
    # is the only thing an unpaid caller can learn about this endpoint.
    if not signature:
        return Response(
            status_code=402,
            headers={"PAYMENT-REQUIRED": server.encode(requirements)},
        )

    settlement = await server.verify_and_settle(signature, requirements)
    if not settlement.ok:
        return Response(status_code=402, content="Payment could not be settled.")

    # Verified. Only now spend anything on their behalf.
    resp = requests.post(
        f"{SENSO}/org/search",
        headers=HEADERS,
        json={"query": q, "max_results": 5},
    )
    resp.raise_for_status()
    body = resp.json()

    sources = {c["content_id"]: c.get("title", "") for c in body.get("results", [])}

    # The receipt and the citations are one audit record. Six months from now a
    # dispute is "what did this buyer actually receive", and only this row knows.
    log_delivery(settlement.transaction, q, list(sources))

    return Response(
        content={"answer": body.get("answer", ""), "sources": sources},
        headers={"PAYMENT-RESPONSE": server.encode(settlement)},
    )

The ordering matters. Verify before you query. A server that runs the search first and checks payment afterwards has already paid for the vector query and the generation, and will do it again for every unpaid request that arrives — which, on a public endpoint, is most of them.

What the buyer sees

An agent using an x402-aware client needs no special handling. The wrapper catches the 402, signs, and retries, so the caller sees one request.

python
from x402 import x402Client
from x402.mechanisms.evm.exact import ExactEvmScheme

client = x402Client()
client.register("eip155:*", ExactEvmScheme(signer=my_signer))
# The wrapper handles 402 -> sign -> retry; the caller just gets an answer.

That is the point of the protocol, and it is also the thing to be careful about: an agent that pays without asking will pay repeatedly. Bound it at the application layer, the way the OpenAI Agents SDK recipe bounds a knowledge lookup.

Buying instead of selling

The same wiring runs backwards. If your agent needs data your knowledge base does not have — a sanctions list, a market feed, a verification service — it can buy that page over x402, then post the result into your knowledge base with POST /org/kb/raw so the next agent to ask does not have to buy it twice.

Paying once and ingesting the answer turns a per-request cost into a fixed one. It also means the purchased fact now goes through the same verification as everything else you publish, rather than living in a single conversation and disappearing.

What to watch

  • Charge for the answer, not the attempt. A query that matches nothing should still return 200 with an empty result set, not a paid non-answer. Buyers who get billed for silence do not come back.
  • Rate-limit anyway. Payment is not authentication. A paying caller can still hammer you, and every request costs you a vector query even when it is settled.
  • Scope the key behind the endpoint. The API key your server uses should reach only the folders you intend to sell. See Permissions.

Where to take it next

  • Read Core Concepts for what "compiled" means — an uncompiled source returns nothing, and a paid endpoint returning nothing is a refund
  • Serve the same knowledge free to your own agents over the MCP Server
  • Use Analytics to see which questions buyers ask, which is the clearest signal you will get about what to write next