monetize-service
coinbase/agentic-wallet-skills
Build and deploy a paid API that other agents can pay to use via x402 payment protocol.
What is monetize-service?
Create an Express server that charges USDC per request for API access using the x402 HTTP payment protocol. Callers pay in real-time on Base blockchain with no accounts or subscriptions needed. Your service is automatically discoverable by other agents via the x402 Bazaar.
- Set up Express middleware that enforces x402 payment requirements on protected endpoints
- Configure per-request USDC pricing on Base mainnet or testnet
- Register endpoints with the x402 Bazaar for automatic agent discovery
- Support multiple endpoints with different price points
- Return HTTP 402 payment requirements that clients can fulfill automatically
- Receive USDC payments directly to your wallet address
How to install monetize-service
npx skills add https://github.com/coinbase/agentic-wallet-skills --skill monetize-service- Authenticated Coinbase wallet (use authenticate-wallet skill if needed)
- Node.js and npm installed
- Express.js knowledge
How to use monetize-service
- 1.Run 'npx awal@2.10.0 status' to confirm wallet is authenticated
- 2.Run 'npx awal@2.10.0 address' to get your payment address
- 3.Create a new directory and run 'npm init -y' and 'npm install express @x402/express @x402/core @x402/evm @x402/extensions'
- 4.Create index.js with Express app, x402ResourceServer, and paymentMiddleware configured with your routes and prices
- 5.Replace <address from step 1> with your actual wallet address in the PAY_TO variable
- 6.Run 'node index.js' to start the server
- 7.Test with 'curl -i http://localhost:3000/api/example' to verify 402 payment response
Use cases
- Monetize a data API by charging agents per query
- Sell access to a specialized ML model or computation service
- Create a premium endpoint tier alongside free endpoints
- Build a marketplace service that other agents discover and pay for automatically
- Charge for real-time data feeds or analytics
- Developers building agent-accessible services
- Teams wanting to monetize APIs without managing accounts or subscriptions
- Service providers targeting the agent economy
- Builders on Coinbase's Base blockchain
monetize-service FAQ
Base mainnet (eip155:8453) for real USDC payments, or Base Sepolia testnet (eip155:84532) for testing.
No. x402 is stateless—each request includes a USDC payment signed by the caller. No accounts, subscriptions, or key management needed.
Register your endpoint with the x402 Bazaar using the declareDiscoveryExtension function. Agents can then find and pay for your service automatically.
Yes. Configure each route separately in the paymentMiddleware routes object with its own price, description, and payment scheme.
The server returns HTTP 402 with payment requirements. The client's agent can then sign a USDC payment and retry with a payment header.
Full instructions (SKILL.md)
Source of truth, from coinbase/agentic-wallet-skills.
name: monetize-service description: Build and deploy a paid API that other agents can pay to use via x402. Use when you or the user want to monetize an API, make money, earn money, offer a service, sell a service to other agents, charge for endpoints, create a paid endpoint, or set up a paid service. Covers "make money by offering an endpoint", "sell a service", "monetize your data", "create a paid API". user-invocable: true disable-model-invocation: false allowed-tools: ["Bash(npx awal@2.10.0 status*)", "Bash(npx awal@2.10.0 address*)", "Bash(npx awal@2.10.0 x402 details *)", "Bash(npx awal@2.10.0 x402 pay *)", "Bash(npm *)", "Bash(node *)", "Bash(curl *)", "Bash(mkdir *)"]
Build an x402 Payment Server
Create an Express server that charges USDC for API access using the x402 payment protocol. Callers pay per-request in USDC on Base — no accounts, API keys, or subscriptions needed. Your service is automatically discoverable by other agents via the x402 Bazaar.
How It Works
x402 is an HTTP-native payment protocol. When a client hits a protected endpoint without paying, the server returns HTTP 402 with payment requirements. The client signs a USDC payment and retries with a payment header. The facilitator verifies and settles the payment, and the server returns the response. Services register with the x402 Bazaar so other agents can discover and pay for them automatically.
Confirm wallet is initialized and authed
npx awal@2.10.0 status
If the wallet is not authenticated, refer to the authenticate-wallet skill.
Step 1: Get the Payment Address
Run this to get the wallet address that will receive payments:
npx awal@2.10.0 address
Use this address as the payTo value.
Step 2: Set Up the Project
mkdir x402-server && cd x402-server
npm init -y
npm install express @x402/express @x402/core @x402/evm @x402/extensions
Create index.js:
const express = require("express");
const { paymentMiddleware } = require("@x402/express");
const { x402ResourceServer, HTTPFacilitatorClient } = require("@x402/core/server");
const { ExactEvmScheme } = require("@x402/evm/exact/server");
const app = express();
app.use(express.json());
const PAY_TO = "<address from step 1>";
// Create facilitator client and x402 resource server
const facilitator = new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" });
const server = new x402ResourceServer(facilitator);
server.register("eip155:8453", new ExactEvmScheme());
// x402 payment middleware — protects routes below
app.use(
paymentMiddleware(
{
"GET /api/example": {
accepts: {
scheme: "exact",
price: "$0.01",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "Description of what this endpoint returns",
mimeType: "application/json",
},
},
server,
),
);
// Protected endpoint
app.get("/api/example", (req, res) => {
res.json({ data: "This costs $0.01 per request" });
});
app.listen(3000, () => console.log("Server running on port 3000"));
Step 3: Run It
node index.js
Test with curl — you should get a 402 response with payment requirements:
curl -i http://localhost:3000/api/example
API Reference
paymentMiddleware(routes, server)
Creates Express middleware that enforces x402 payments.
| Parameter | Type | Description |
|---|---|---|
routes | object | Route config mapping route patterns to payment config |
server | x402ResourceServer | Pre-configured x402 resource server instance |
x402ResourceServer
Created with a facilitator client. Register payment schemes and extensions before passing to middleware.
const { x402ResourceServer, HTTPFacilitatorClient } = require("@x402/core/server");
const { ExactEvmScheme } = require("@x402/evm/exact/server");
const facilitator = new HTTPFacilitatorClient({ url: "https://x402.org" });
const server = new x402ResourceServer(facilitator);
server.register("eip155:8453", new ExactEvmScheme());
| Method | Description |
|---|---|
register(network, scheme) | Register a payment scheme for a CAIP-2 network identifier |
Route Config
Each key in the routes object is "METHOD /path". The value is a config object:
{
"GET /api/data": {
accepts: {
scheme: "exact",
price: "$0.05",
network: "eip155:8453",
payTo: "0x...",
},
description: "Human-readable description of the endpoint",
mimeType: "application/json",
extensions: {
...declareDiscoveryExtension({
output: {
example: { result: "example response" },
schema: {
properties: {
result: { type: "string" },
},
},
},
}),
},
},
}
Accepts Config Fields
The accepts field can be a single object or an array (for multiple payment options):
| Field | Type | Description |
|---|---|---|
scheme | string | Payment scheme: "exact" |
price | string | USDC price (e.g. "$0.01", "$1.00") |
network | string | CAIP-2 network identifier (e.g. "eip155:8453") |
payTo | string | Ethereum address (0x...) to receive USDC payments |
Route-Level Fields
| Field | Type | Description |
|---|---|---|
accepts | object or array | Payment requirements (single or multiple) |
description | string? | What this endpoint does (shown to clients) |
mimeType | string? | MIME type of the response |
extensions | object? | Extensions config (e.g. Bazaar discovery) |
Discovery Extension
The declareDiscoveryExtension function registers your endpoint with the x402 Bazaar so other agents can discover it:
const { declareDiscoveryExtension } = require("@x402/extensions/bazaar");
extensions: {
...declareDiscoveryExtension({
output: {
example: { /* example response body */ },
schema: {
properties: {
/* JSON schema of the response */
},
},
},
}),
}
| Field | Type | Description |
|---|---|---|
output.example | object | Example response body for the endpoint |
output.schema | object | JSON schema describing the response format |
Supported Networks
| Network | Description |
|---|---|
eip155:8453 | Base mainnet (real USDC) |
eip155:84532 | Base Sepolia testnet (test USDC) |
Patterns
Multiple endpoints with different prices
app.use(
paymentMiddleware(
{
"GET /api/cheap": {
accepts: {
scheme: "exact",
price: "$0.001",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "Inexpensive data lookup",
},
"GET /api/expensive": {
accepts: {
scheme: "exact",
price: "$1.00",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "Premium data access",
},
"POST /api/query": {
accepts: {
scheme: "exact",
price: "$0.25",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "Run a custom query",
},
},
server,
),
);
app.get("/api/cheap", (req, res) => { /* ... */ });
app.get("/api/expensive", (req, res) => { /* ... */ });
app.post("/api/query", (req, res) => { /* ... */ });
Wildcard routes
app.use(
paymentMiddleware(
{
"GET /api/*": {
accepts: {
scheme: "exact",
price: "$0.05",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "API access",
},
},
server,
),
);
app.get("/api/users", (req, res) => { /* ... */ });
app.get("/api/posts", (req, res) => { /* ... */ });
Health check (no payment)
Register free endpoints before the payment middleware:
app.get("/health", (req, res) => res.json({ status: "ok" }));
// Payment middleware only applies to routes registered after it
app.use(paymentMiddleware({ /* ... */ }, server));
app.get("/api/data", (req, res) => { /* ... */ });
POST with body and discovery extension
app.use(
paymentMiddleware(
{
"POST /api/analyze": {
accepts: {
scheme: "exact",
price: "$0.10",
network: "eip155:8453",
payTo: PAY_TO,
},
description: "Analyze text sentiment",
mimeType: "application/json",
extensions: {
...declareDiscoveryExtension({
output: {
example: { sentiment: "positive", score: 0.95 },
schema: {
properties: {
sentiment: { type: "string" },
score: { type: "number" },
},
},
},
}),
},
},
},
server,
),
);
app.post("/api/analyze", (req, res) => {
const { text } = req.body;
// ... your logic
res.json({ sentiment: "positive", score: 0.95 });
});
Multiple payment options per endpoint
Accept payments on multiple networks for the same endpoint:
"GET /api/data": {
accepts: [
{
scheme: "exact",
price: "$0.01",
network: "eip155:8453",
payTo: EVM_ADDRESS,
},
{
scheme: "exact",
price: "$0.01",
network: "eip155:84532",
payTo: EVM_ADDRESS,
},
],
description: "Data endpoint accepting Base mainnet or testnet",
}
Using the CDP facilitator (authenticated)
For production use with the Coinbase facilitator (supports mainnet):
npm install @coinbase/x402
const { facilitator } = require("@coinbase/x402");
const { HTTPFacilitatorClient } = require("@x402/core/server");
const facilitatorClient = new HTTPFacilitatorClient(facilitator);
const server = new x402ResourceServer(facilitatorClient);
server.register("eip155:8453", new ExactEvmScheme());
This requires CDP_API_KEY_ID and CDP_API_KEY_SECRET environment variables. Get these from https://portal.cdp.coinbase.com.
Testing with the pay-for-service Skill
Once the server is running, use the pay-for-service skill to test payments:
# Check the endpoint's payment requirements
npx awal@2.10.0 x402 details http://localhost:3000/api/example
# Make a paid request
npx awal@2.10.0 x402 pay http://localhost:3000/api/example
Pricing Guidelines
| Use Case | Suggested Price |
|---|---|
| Simple data lookup | $0.001 - $0.01 |
| API proxy / enrichment | $0.01 - $0.10 |
| Compute-heavy query | $0.10 - $0.50 |
| AI inference | $0.05 - $1.00 |
Checklist
- Get wallet address with
npx awal@2.10.0 address - Install
express,@x402/express,@x402/core,@x402/evm, and@x402/extensions - Create
x402ResourceServerwith facilitator client and registerExactEvmSchemeforeip155:8453 - Define routes with prices, descriptions, and discovery extensions (Bazaar auto-registers when routes declare it)
- Register payment middleware before protected routes
- Keep health/status endpoints before payment middleware
- Test with
curl(should get 402) andnpx awal@2.10.0 x402 pay(should get 200) - Announce your service so other agents can find and use it
Related skills
More from coinbase/agentic-wallet-skills and the wider catalog.

pay-for-service
Call paid APIs with automatic USDC payment on Base via x402 protocol.

query-onchain-data
Query onchain data on Base using the CDP SQL API via x402 with decoded events, transactions, and blocks.

search-for-service
Search and browse the x402 bazaar marketplace for paid API services.

send-usdc
Send USDC, ETH, POL, or SOL to any address or ENS name on Base, Polygon, or Solana.

trade
Swap or trade tokens on Base or Polygon networks via the CDP Swap API.

x402
Search and call paid APIs using the x402 payment protocol with automatic USDC payments on Base.