docs · complete guide

Build paid APIs for agents, apps, and users.

Verge is an HTTP 402 gateway and SDK. Your server returns a payment challenge, the caller pays on a supported rail, then retries with the transaction proof. Robinhood Chain + USDG is the default; other rails are selected with a single network option.

Overview

What is x402?

A protocol pattern for HTTP 402 Payment Required: request → challenge → payment → retry → access.

Who pays?

Agents, apps, scripts, or humans. The protocol is not agent-only; agents are the strongest use case because they can pay per request automatically.

What does Verge add?

Express/Hono middleware, stablecoin verification, replay protection hooks, wallet console, marketplace listings, API keys, receipts, and a machine-readable catalog.

Install

Pick the adapter for your server framework. Both adapters call the same @vergex402/core verifier.

npm install @vergex402/express
npm install @vergex402/hono hono

Environment you normally need:

WALLET=0xYourRecipientWallet
# optional: overrides the public/default RPC for the selected network
ROBINHOOD_RPC_URL=https://rpc.mainnet.chain.robinhood.com
# optional: used as primary RPC when configured
ALCHEMY_API_KEY=...

Express quickstart

import express from "express";
import { paywall } from "@vergex402/express";

const app = express();
const recipient = process.env.WALLET;
if (!recipient) throw new Error("WALLET is required");

app.use("/api/premium", paywall({
  amount: 0.001,
  recipient,
  network: "robinhood-mainnet", // default rail: USDG on chain 4663
}));

app.get("/api/premium", (_req, res) => {
  res.json({ ok: true, message: "unlocked" });
});

app.listen(3000);

Hono quickstart

import { Hono } from "hono";
import { paywall } from "@vergex402/hono";

const app = new Hono();
const recipient = process.env.WALLET;
if (!recipient) throw new Error("WALLET is required");

app.use("/api/premium", paywall({
  amount: 0.001,
  recipient,
  network: "robinhood-mainnet",
}));

app.get("/api/premium", (c) => c.json({ ok: true, message: "unlocked" }));

The x402 request flow

  1. 1. Caller requests a protected route. Without proof, Verge returns HTTP 402 and payment headers.
  2. 2. Caller pays the requested asset. The challenge includes amount, recipient, network, token reference, and nonce.
  3. 3. Caller retries with proof. Send X-Pay-Tx and X-Pay-Nonce.
  4. 4. Middleware verifies settlement. EVM rails check stablecoin Transfer logs; Solana and Sui use their own transaction/balance verification paths.
curl -i http://localhost:3000/api/premium

HTTP/1.1 402 Payment Required
WWW-Authenticate: x402 realm="verge", nonce="8f3c2d", amount="0.001", recipient="0x...", network="robinhood-mainnet"
X-Pay-Token: USDG
X-Pay-Network: robinhood-mainnet
X-Pay-Chain-Id: 4663
X-Pay-Amount: 0.001
X-Pay-Recipient: 0x...
X-Pay-Nonce: 8f3c2d
curl -i http://localhost:3000/api/premium   -H "X-Pay-Tx: 0xYourSettlementTx"   -H "X-Pay-Nonce: 8f3c2d"

HTTP/1.1 200 OK
{ "ok": true, "message": "unlocked" }

Client retry helper

A caller does not need a Verge account. It only needs to understand the 402 response, pay the requested rail, then retry with the proof headers. The core package now exports helpers for parsing the challenge and building retry headers.

import { parseX402Authenticate, paymentProofHeaders } from "@vergex402/core";

const first = await fetch("https://api.example.com/premium");
if (first.status === 402) {
  const challenge = parseX402Authenticate(first.headers.get("www-authenticate") || "");
  // Your wallet/payment engine sends challenge.amount to challenge.recipient
  // on challenge.network, then returns the settlement transaction hash.
  const txHash = await payStablecoin(challenge);

  const unlocked = await fetch("https://api.example.com/premium", {
    headers: paymentProofHeaders(txHash, challenge.nonce),
  });
}

Security model

Issued nonce required

A paid retry must present a nonce that the middleware actually issued. Unknown or already-consumed nonces return NONCE_INVALID.

Replay-safe transaction hashes

Each tx hash is keyed by network and rejected after the first successful unlock. Use a durable ReplayStore in multi-process production.

Settlement verification

EVM rails inspect stablecoin Transfer logs; Solana inspects SPL token-balance deltas; Sui inspects finalized balance changes.

Stateless option

The built-in stores are in-memory for simple servers. Bring Redis/Postgres stores when running multiple workers or serverless replicas.

Multichain: one option, not a different command

You were right to ask: every chain has its own identifier, token, verifier path, and RPC. In Verge, you do not run a different command for each chain. You set network in the SDK options. If omitted, Verge uses robinhood-mainnet. The 402 response tells the caller which network, token, recipient, amount, and nonce to use.

Network stringChainChain IDAssetNotes
robinhood-mainnetRobinhood Chain4663USDGDefault / flagship rail
ethereum-mainnetEthereum1USDCExplicit opt-in EVM rail
base-mainnetBase8453USDCExplicit opt-in EVM rail
arbitrum-mainnetArbitrum One42161USDCExplicit opt-in EVM rail
polygon-mainnetPolygon137USDCExplicit opt-in EVM rail
solana-mainnetSolanaSVMUSDCExplicit opt-in SVM rail
sui-mainnetSuiMoveUSDCExplicit opt-in Move rail
app.use("/api/premium", paywall({
  amount: 0.001,
  recipient,
  network: "base-mainnet", // or ethereum-mainnet, arbitrum-mainnet, polygon-mainnet, solana-mainnet, sui-mainnet
}));

Current app reality: the public catalog shows all supported rails; private wallet balances and transaction history in the console are Robinhood Chain-focused today.

Developer portal / console

The console is the user-facing workspace. Visitors can explore payment rails and the marketplace before connecting. Wallet connection is only required for private actions.

Overview: wallet balance, endpoint count, paid calls, settlement volume
Transactions: confirmed incoming stablecoin transfers
Marketplace: browse and publish paid endpoints
Receipts: explorer-linked settlement proofs
API Keys: create/revoke wallet-scoped credentials
Networks: rail registry, token reference, explorer links, SDK snippets

API keys

API keys are for apps that want Verge-managed access without forcing every request to carry a payment transaction. A wallet signs into the console, creates a key, and your server can introspect it.

curl -X POST https://vergesnowy.com/api/keys/verify   -H "content-type: application/json"   -d '{"key": "vg_live_..."}'

{ "ok": true, "wallet": "0xabc...", "remaining": 998, "limit": 1000 }

Introspection reports validity, revocation state, and remaining quota. Unknown, revoked, or exhausted keys return HTTP 401.

Marketplace and catalog

The marketplace is the human UI for paid endpoints. /api/catalog is the machine-readable version for agents and crawlers. Use it to discover endpoints, supported rails, docs URL, gateway URL, and demo routes.

curl https://vergesnowy.com/api/catalog
curl https://vergesnowy.com/api/marketplace
curl https://vergesnowy.com/api/demo

Reference