> For the complete documentation index, see [llms.txt](https://docs.vapinetwork.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vapinetwork.ai/call/sell-on-call/list-your-api.md).

# List your API

List a provider-hosted x402 API on vAPI Call: serve a USDC offer on Base, pass the automated probe, deploy your FeeSplitter, and go live without waiting for a review.

Listing on Call is permissionless: your API goes live the moment its endpoints pass the automated x402 probe and your FeeSplitter is verified on chain. No review is needed to be listed; [verification](/call/sell-on-call/get-verified.md) is a separate tier that puts you in default search. Prepare the payment challenge, OpenAPI metadata, and browser access before you publish.

## What a listing needs

| Piece        | Requirement                                                                                                                                                                                           |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 402 response | Return x402 v2 with the `exact` scheme in both the JSON body and the base64 `PAYMENT-REQUIRED` header for a clean conformance check. An otherwise valid offer in either carrier lists with a warning. |
| Asset        | Use canonical USDC on Base, `eip155:8453`, at `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`.                                                                                                           |
| `payTo`      | Set `payTo` to your FeeSplitter address on Base because the splitter is the provider's immutable payout address.                                                                                      |
| OpenAPI      | For OpenAPI publishing, declare a `402` response and `x-payment-info` on every paid operation. A single concrete endpoint can be listed without OpenAPI.                                              |
| CORS         | For browser calls, allow the console origin and expose `PAYMENT-REQUIRED` and `PAYMENT-RESPONSE` to browser JavaScript. Listing can succeed without confirmed CORS, with a warning.                   |

## A minimal paid endpoint

Replace the example `payTo` value in the handler with the FeeSplitter address the publish wizard predicts for your payout wallet. This Hono handler uses the Coinbase x402 facilitator at `https://x402.org/facilitator`. It returns the same v2 fields as the real 402 sample, including the resource and payment option fields.

```ts
import { Hono } from "hono";
import { cors } from "hono/cors";
import { serve } from "@hono/node-server";

const app = new Hono();
const facilitator = "https://x402.org/facilitator";
const payTo = "0x7B5592D2F8adBF58b4A69b374636EC918F21eFAb"; // replace with your FeeSplitter
const offer = {
  x402Version: 2,
  error: "Payment required",
  resource: { url: "http://localhost:4242/paid", description: "A paid example resource.", mimeType: "application/json", serviceName: "Provider API" },
  accepts: [{ scheme: "exact", network: "eip155:8453", amount: "5000", asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", payTo, maxTimeoutSeconds: 120, extra: { name: "USD Coin", version: "2" } }],
};
app.use("*", cors({ origin: "*", exposeHeaders: ["PAYMENT-REQUIRED", "PAYMENT-RESPONSE"] }));
app.get("/openapi.json", (c) => c.json({ openapi: "3.0.3", info: { title: "Provider API", version: "1.0.0" }, paths: { "/paid": { post: { "x-payment-info": offer.accepts[0], responses: { "200": { description: "Paid response" }, "402": { description: "Payment required" } } } } } }));
app.post("/paid", async (c) => {
  const encoded = c.req.header("PAYMENT-SIGNATURE");
  if (!encoded) return c.json(offer, 402, { "PAYMENT-REQUIRED": btoa(JSON.stringify(offer)) });
  let payment;
  try { payment = JSON.parse(atob(encoded)); } catch { return c.json({ error: "Invalid payment" }, 400); }
  const body = { x402Version: 2, paymentPayload: payment, paymentRequirements: offer.accepts[0] };
  const headers = { "content-type": "application/json" };
  const verify = await fetch(`${facilitator}/verify`, { method: "POST", headers, body: JSON.stringify(body) });
  const verified = await verify.json();
  if (!verify.ok || !verified.isValid) return c.json({ error: "Payment verification failed" }, 402);
  const settle = await fetch(`${facilitator}/settle`, { method: "POST", headers, body: JSON.stringify(body) });
  const settlement = await settle.json();
  if (!settle.ok || !settlement.success) return c.json({ error: "Payment settlement failed" }, 502);
  return c.json({ resource: offer.resource }, 200, { "PAYMENT-RESPONSE": btoa(JSON.stringify(settlement)) });
});
serve({ fetch: app.fetch, port: 4242 });
```

## Run it

Create a temporary project, install the two packages, save the TypeScript-compatible handler as `index.mjs`, and run it with Node. The command checks the POST route without opening a wallet or paying.

```bash
mkdir -p /tmp/vapi-call && cd /tmp/vapi-call
npm init -y && npm i hono @hono/node-server
node index.mjs
```

## Check it

Run `vapi check` against the running endpoint. It grades the 402 the way a buyer client reads it, without paying. The extension and discovery warnings are expected for this minimal example.

The client refuses private hosts by default. For a local server, set `allowPrivateNetwork` to `true` in the client config (`~/.vapi/config.json`, created by `vapi init`) before you run the check; remove it again when you are done.

```bash
vapi check http://localhost:4242/paid --method POST
```

```
Check: POST http://localhost:4242/paid — HTTP 402
  pass  status      HTTP 402 Payment Required.
  pass  transport   The offer is in the PAYMENT-REQUIRED header and the body.
  pass  version     Declares x402 version 2.
  pass  fields      Every field x402 v2 requires is present and well-typed.
  pass  scheme      1 of 1 accepted option uses the exact scheme.
  pass  asset       Pays canonical USDC on eip155:8453.
  pass  pay_to      Every exact option names a well-formed payTo address.
  pass  timeout     maxTimeoutSeconds 120.
  warn  extensions  Advertises none of the known extensions. Adding Bazaar metadata makes the API discoverable in Coinbase's Bazaar and by Coinbase for Agents. [bazaar_metadata_missing]
  warn  discovery   No discovery document at http://localhost:4242/.well-known/x402: HTTP 404. [discovery_missing]
  pass  openapi     http://localhost:4242/openapi.json declares x-payment-info for POST /paid.
9 passed, 2 warnings, 0 failed.
```

## Publish

Open **Add API** at [api.vapinetwork.ai/call/my-apis/new](https://api.vapinetwork.ai/call/my-apis/new), or use the CLI commands below. The wizard has five steps:

1. Probe: submit your origin, endpoint, or OpenAPI URL so the registry discovers and validates the payable operations.
2. OpenAPI: select operations whose document includes `x-payment-info` and a `402` response.
3. Payout wallet proof: sign the payout message with the wallet that receives your Call payouts.
4. FeeSplitter: deploy the predicted FeeSplitter on Base from your wallet.
5. Go live: press `Go live` so activation re-probes every endpoint and verifies the deployed splitter on chain.

```bash
vapi auth set-key
vapi publish https://your-api.example --mode origin --select paid --name "Provider API" --description "Paid API" --category data
vapi publish activate <slug>
```

<figure><picture><source srcset="/files/dRqRAB1J26n7zXR7vCId" media="(prefers-color-scheme: dark)"><img src="https://565465579-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC8O04QfdFicZZcqBGUz5%2Fuploads%2Fgit-blob-71a22eee15c0bbf27205c10622f16569b9a1a365%2Fvapi-list-api-lifecycle-light.svg?alt=media" alt="A provider listing from publish to recovery. Publish in the console at /call/my-apis/new or with vapi publish, in five steps: 1, Probe finds the payable operations; 2, OpenAPI needs x-payment-info and a 402 response on each; 3, Payout proof is signed with the payout wallet; 4, FeeSplitter is deployed once per enabled network; 5, Go live re-probes and checks the splitter onchain. When activation passes, the listing is live: in discovery, with buyers paying your FeeSplitter per call. This splitter flow applies to self-listed APIs and Partners added through the website. Direct-payout Partners use their own payout address. Two separate rails follow. Get verified: request review from My APIs or with vapi publish verify-request, reviewers check it while the listing stays live, and verification adds the listing to default search and raises its trust score. Stay live: an hourly recheck against the activation rules; three consecutive failures suspend the listing, remove it from discovery and leave its tier unchanged; fix the endpoint and press Go live on My APIs to return to live."></picture><figcaption><p>Verification and liveness run on separate rails. A suspension never changes the verification tier.</p></figcaption></figure>

## Get verified

Verification is a review tier for a live listing, and the listing stays live while review is pending. Request it from My APIs or run `vapi publish verify-request <slug>` after activation. Read [Get verified](/call/sell-on-call/get-verified.md) for the review checks and request flow.

## Stay live

Self-listed and Partner APIs are rechecked every hour against the activation rules. Three consecutive failed checks add three strikes, suspend the listing, and remove it from discovery without changing its verification tier. Fix the endpoint, press `Go live` on My APIs, and read [Stay live](/call/sell-on-call/stay-live.md) for the recovery flow.

Checked on 2026-10-15.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.vapinetwork.ai/call/sell-on-call/list-your-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
