Working x402 + Base USDC example

Sell an MCP tool or API call with Pyrimid.

This guide separates three concerns that are easy to blur together: describing a product, returning an HTTP 402 challenge, and routing a buyer's USDC through Pyrimid so the protocol, affiliate, and vendor shares settle atomically.

Live checks used for this guide

1. Describe one bounded product

Use a stable product identifier, one endpoint, one HTTP method, a price in atomic USDC, and a narrow output contract. Avoid promising facts or capabilities that the endpoint does not verify.

{
  "vendor_id": "your-vendor-id",
  "product_id": "public-url-evidence",
  "description": "Bounded HTTP metadata and SHA-256 evidence for one public URL",
  "category": "security",
  "tags": ["x402", "base", "url", "evidence"],
  "price_usdc": 20000,
  "price_display": "$0.02",
  "affiliate_bps": 2000,
  "endpoint": "https://holder-victor-nova-mag.trycloudflare.com/x402/url-evidence?url=https%3A%2F%2Fexample.com",
  "method": "GET",
  "network": "base",
  "asset": "USDC"
}

2. Return a machine-readable 402 challenge

The unpaid request must return status 402. The challenge should identify the exact resource, Base network, USDC asset, amount, recipient or router, and response media type. SiteSignal uses the standard PAYMENT-REQUIRED header; the current Pyrimid seed route also exposes X-PAYMENT-REQUIRED.

curl -i 'https://pyrimid.ai/api/v1/paid/signals'

HTTP/2 402
x-pyrimid-network: base
x-pyrimid-vendor: pragma-trading
x-pyrimid-product: pragma-signal-snapshot
x-payment-required: {
  "x402Version": 2,
  "scheme": "exact",
  "network": "base",
  "asset": "USDC",
  "maxAmountRequired": "0.25",
  "payTo": "0xc949AEa380D7b7984806143ddbfE519B03ABd68B",
  "vendorId": "pragma-trading",
  "productId": "pragma-signal-snapshot",
  "affiliateBps": 5000,
  "protocol": "pyrimid"
}

3. Register the vendor and product

Pyrimid's current vendor path is on Base. Register the service and payout address in PyrimidRegistry, then list the endpoint and commission in PyrimidCatalog. A commission of 2000 basis points means 20%; the protocol currently enforces a 5–50% range.

// Registry: 0x34e22fc20D457095e2814CdFfad1e42980EEC389
registry.registerVendor("SiteSignal", "https://holder-victor-nova-mag.trycloudflare.com", "0xD8049F6998E05C437C970815eF1094aC6241e948")

// Catalog: 0xC935d6B73034dDDb97AD2a1BbD2106F34A977908
catalog.listProduct(
  vendorId,
  1,
  "https://holder-victor-nova-mag.trycloudflare.com/x402/url-evidence?url=https%3A%2F%2Fexample.com",
  "Bounded public-URL evidence snapshot",
  20000,
  2000
)

4. Gate affiliate-tagged requests

Keep the existing endpoint and its normal x402 middleware. Add Pyrimid's gate only for requests carrying an affiliate identifier, so direct buyers continue to work while distributed purchases route through the commission contract.

import { pyrimidMiddleware } from '@pyrimid/sdk';

app.use(pyrimidMiddleware({
  vendorId: 'vn_your_id',
  products: {
    '/x402/url-evidence': {
      productId: 'public-url-evidence',
      price: 20_000,
      affiliateBps: 2_000
    }
  }
}));

5. Verify the complete sale

  1. Confirm the product appears in Pyrimid's catalog API.
  2. Make an unpaid request and verify status 402 plus the expected product, network, asset, and maximum price.
  3. Route a genuine buyer payment; do not treat a self-payment as market demand.
  4. Confirm a PaymentRouted event on Base and reconcile the protocol, affiliate, and vendor transfers.
  5. Retry with the documented payment proof and verify the paid response satisfies the published output contract.
Operational boundaries

Never log wallet private keys or full payment authorizations. Reject unknown networks, assets, recipients, prices above the buyer's ceiling, reused proofs, private-network input URLs, and any response that cannot be linked to a settled transaction. Catalog presence alone is discovery—not evidence of revenue.