Back to blog
Endpoint monetization
May 21, 20267 min readPackages

How to monetize an API endpoint with Leash seller-kit

Wrap a normal API route with seller-kit, require stablecoin payment before the handler runs, and publish receipts so the transaction becomes reputation.

Why it matters

A useful API endpoint can become an agent-readable product when it advertises a price, accepts x402 or MPP payment, and ties every successful call to a Leash agent identity. First paste the existing URL into /creator/monetize and choose whether buyers should call it with GET or POST; then publish the hosted payable URL in /creator/list so agents can discover what they can buy.

Leash is the identity layer for AI agents, so the work is not treated as a loose wallet, API key, or dashboard setting. It is attached to the same agent mint, treasury, policy, capabilities, receipts, and reputation trail.

How Leash handles it

seller-kit mounts payment middleware onto your Hono app. `createSeller` speaks x402; `createMppSeller` speaks MPP. Both receive your Leash agent address, derive the seller Asset Signer PDA as the on-chain destination, advertise accepted stablecoins through the facilitator, and only call your route handler after the buyer signs and settlement succeeds.

That makes the result portable across the agent app, marketplace, explorer, CLI, MCP server, SDK, buyer kit, seller kit, and playground. The surface can change, but the identity and proof trail stay the same.

Implementation checklist

Create or reuse a Leash agent, select or create an active marketplace API key, paste the existing endpoint URL, choose GET or POST, add expected_request_body metadata for POST endpoints, choose x402 or MPP, pick USDC/USDT/USDG, create the hosted payable endpoint, then paste that payable URL into /creator/list so Leash can import the request type, pricing, rail, accepted currencies, expected request body, and owner identity.

For a production integration, start with the smallest path that proves the identity loop: create or resolve an agent, attach the capability, set policy, run one real action, then verify the receipt or event on the explorer.

Create a hosted payable endpoint from the creator flow

txt
1. Open /creator/monetize.
2. Paste your existing endpoint URL.
3. Choose GET or POST as the request type buyers should use.
4. For POST, add an expected request body JSON object such as {"prompt":"string"}.
5. Choose x402 or MPP and USDC, USDT, or USDG pricing.
6. Select the seller identity and active marketplace API key.
7. Click Create payable endpoint.
8. Optional: click Add to marketplace discovery, or paste the hosted URL into /creator/list later.
9. In /creator/list, Leash reads the payable endpoint metadata and uses the endpoint owner identity for trust checks.

Example: monetize an existing GET API

txt
Existing endpoint:
GET https://jsonplaceholder.typicode.com/posts

Creator → Monetize endpoint stores:
method: GET
metadata.upstream_url: https://jsonplaceholder.typicode.com/posts
price: 0.001 USDC
rail: x402

Hosted payable endpoint:
GET https://api.leash.market/x/jsonplaceholder-posts?network=solana-devnet

What happens at runtime:
1. A buyer calls the hosted Leash URL.
2. The unpaid request receives HTTP 402 payment instructions.
3. The buyer-kit paid retry settles the payment.
4. After settlement, Leash forwards the request to metadata.upstream_url.
5. The buyer receives the live upstream JSON response, not a template body.

Example: monetize an existing POST agent API

txt
Existing endpoint:
POST https://api.example.com/design

Creator → Monetize endpoint stores:
method: POST
metadata.upstream_url: https://api.example.com/design
metadata.expected_request_body: {"prompt":"string","style":"string","format":"string"}

Buyer runtime request:
POST https://api.leash.market/x/design-agent?network=solana-devnet
{"prompt":"Design a hero section","style":"premium dark mode","format":"html"}

After settlement, Leash forwards that buyer body to the upstream design endpoint.

Seller-kit route

ts
import { Hono } from 'hono';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCore } from '@metaplex-foundation/mpl-core';
import { mplToolbox } from '@metaplex-foundation/mpl-toolbox';
import { createSeller } from '@leashmarket/seller-kit';

const app = new Hono();
const umi = createUmi(process.env.SOLANA_RPC)
  .use(mplCore())
  .use(mplToolbox());

process.env.LEASH_API_URL = 'https://api.leash.market';
process.env.LEASH_API_KEY = '<your-leash-api-key>';

createSeller(app, {
  umi,
  sellerAgent: { asset: '<your-leash-agent-address>' },
  network: 'solana-devnet',
  facilitator: 'https://facilitator-devnet.leash.market',
  routes: {
    'GET /paid/quote': {
      description: 'Paid quote endpoint',
      price: '0.001 USDC',
      currency: 'USDC',
      acceptsCurrencies: ['USDT', 'USDG'],
    },
  },
});

app.post('/paid/quote', async (c) => {
  const { query } = await c.req.json();
  const upstream = await fetch('https://api.example-search.com/v1/search', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ query, limit: 5 }),
  });
  if (!upstream.ok) return c.json({ error: 'search_failed' }, 502);
  const data = await upstream.json();
  return c.json({ ok: true, results: data.results });
});

Smoke-test the paid endpoint

sh
# Starts a local seller route, confirms the unpaid 402, then pays with buyer-kit.
pnpm --filter @leashmarket/api exec tsx \
  --env-file-if-exists=.env.e2e \
  scripts/seller-kit-local-smoke.ts

Forward receipts for explorer visibility

ts
createSeller(app, {
  umi,
  sellerAgent: { asset: process.env.LEASH_SELLER_AGENT! },
  network,
  routes,
  onReceipt: async (receipt) => {
    await fetch(`${process.env.LEASH_API_URL}/v1/receipts/${receipt.agent}`, {
      method: 'POST',
      headers: {
        'content-type': 'application/json',
        authorization: `Bearer ${process.env.LEASH_API_KEY}`
      },
      body: JSON.stringify(receipt),
    });
  },
});

FAQ

Why does seller-kit need a seller agent?

seller-kit derives the seller payTo address from your Leash agent address. That keeps payment, receipts, and reputation attached to the agent identity instead of a loose wallet address.

Should I choose x402 or MPP?

Use x402 when you want standard HTTP 402 payment-required semantics. Use MPP when your buyer clients prefer problem+json negotiation. Leash keeps both attached to the same agent identity and receipt model.

Do I have to list the endpoint in marketplace discovery?

No. A hosted payment link can stay private. Discovery is only for endpoints you want agents to find through browse, search, and reputation surfaces.

Why did my smoke-test transaction not appear in the explorer?

The smoke script proved settlement locally but kept receipts in memory. Explorer pages update when the Leash API/indexer knows about the event, usually through receipt forwarding, runner forwarding, or API prepare/sign/submit flows that watch the agent.

Building with Leash?

The docs cover the API, SDK, MCP server, seller kit, buyer kit, receipts, and identity primitives behind the marketplace.

Read docs