Skip to main content

Config File

The bankr.x402.json file defines your x402 Cloud services — pricing, methods, and schemas for agent discovery.

Created automatically by bankr x402 init and updated by bankr x402 add and bankr x402 configure.

Example

{
"network": "base",
"currency": "USDC",
"services": {
"weather": {
"description": "Real-time weather data for any city",
"price": "0.001",
"methods": ["GET"],
"category": "data",
"tags": ["weather", "forecast"],
"schema": {
"input": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name" },
"units": {
"type": "string",
"description": "Temperature units",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
},
"output": {
"type": "object",
"properties": {
"temperature": {
"type": "number",
"description": "Current temperature"
},
"conditions": {
"type": "string",
"description": "Weather conditions"
}
}
}
}
},
"sentiment": {
"description": "AI-powered sentiment analysis",
"price": "0.01",
"methods": ["POST"],
"schema": {
"input": {
"type": "object",
"properties": {
"text": { "type": "string", "description": "Text to analyze" }
},
"required": ["text"]
},
"output": {
"type": "object",
"properties": {
"sentiment": {
"type": "string",
"description": "positive, negative, or neutral"
},
"score": {
"type": "number",
"description": "Sentiment score from -1 to 1"
},
"confidence": {
"type": "number",
"description": "Confidence level 0-1"
}
}
}
}
}
}
}

Top-Level Fields

FieldDefaultDescription
payToYour Bankr walletWallet address to receive payments
network"base"Blockchain network
currency"USDC"Token symbol (display only)
tokenAddressnull (USDC)ERC-20 contract address. Defaults to USDC; set any ERC-20 to price in that token — see Custom Tokens

Service Fields

Each key in services is the service name. Names must be alphanumeric, hyphens, or underscores — max 47 characters.

FieldDefaultDescription
price"0.001"Price per request in the configured token (minimum: 0.000001)
descriptionHuman-readable description shown to agents during discovery
methods["GET", "POST"]Accepted HTTP methods
currencyInherits top-levelToken symbol (display only)
networkInherits top-levelBlockchain network
tokenAddressInherits top-levelERC-20 contract address
categoryCategory for discovery
tags[]Tags for discovery search
paymentSchemeautoPayment scheme: "exact" (fixed price) or "upto" (usage-based, settle actual cost). Optional — when omitted, the platform auto-selects per token (EIP-3009 tokens like USDC/EURC default to exact; other ERC-20s default to upto via Permit2). You can override either default: set "exact" for a fixed price (custom tokens settle the full amount on the Permit2 rail) or "upto" for usage-based billing on any token
schemaInput/output schema for agent discovery (see below)

Service-level currency, network, and tokenAddress override the top-level defaults.

Payment Schemes

The paymentScheme field controls how payments are authorized and settled. It's optional — leave it off and the platform picks a sensible default for the configured token (EIP-3009 tokens like USDC/EURC default to exact; other ERC-20s default to upto via Permit2). Both defaults are overridable: any token can run either scheme.

Exact

The client pays exactly the listed price for every request. This is the simplest model — one price, one payment. It's the default for EIP-3009 tokens (USDC, EURC), and you can set it on a custom ERC-20 too — that token settles the full fixed price on the Permit2 rail.

{
"services": {
"weather": {
"price": "0.001",
"paymentScheme": "exact"
}
}
}

Upto (usage-based)

The client authorizes up to the listed price, but your handler reports the actual cost via the X-402-Settle-Amount response header. Only the actual amount is settled on-chain.

This is ideal for endpoints where cost varies per request — for example, processing a variable number of items, or calling an LLM where token count differs.

{
"services": {
"batch-process": {
"price": "0.01",
"paymentScheme": "upto",
"description": "Process 1-20 items at $0.0005 each",
"methods": ["GET"]
}
}
}

How it works:

  1. The 402 response advertises the price as the maximum cost
  2. The caller authorizes up to that amount via Permit2
  3. Your handler runs and sets X-402-Settle-Amount to the actual cost, in the configured token's atomic units (6 decimals for USDC, e.g. "500" = $0.0005)
  4. The router settles only the actual amount on-chain
// In your handler — set the actual cost
return new Response(JSON.stringify(result), {
headers: {
"Content-Type": "application/json",
"X-402-Settle-Amount": String(actualCostAtomicUsdc),
},
});

If your handler doesn't set X-402-Settle-Amount, the full price is settled as a fallback.

Permit2 Approval

The upto scheme uses Permit2 for payment authorization. Callers using the Bankr API or CLI have this handled automatically. If you're building a custom x402 client, the caller's wallet needs a one-time ERC-20 approval of USDC to the Permit2 contract (0x000000000022D473030F116dDEE9F6B43aC78BA3).

Schema

The schema field describes your service's inputs and outputs using JSON Schema so AI agents can discover and call your endpoint automatically.

The schema has two fields:

FieldDescription
inputJSON Schema object describing request parameters. For GET services, properties map to query params. For POST services, properties map to JSON body fields.
outputJSON Schema object describing the response shape.

Each schema is a JSON Schema object with properties, optional required array, and optional description on each property.

Supported JSON Schema properties

PropertyDescription
type"string", "number", "integer", "boolean", "array", "object"
descriptionHuman-readable description of the field
requiredArray of required property names (on the parent object)
enumArray of allowed values
itemsSchema for array items
propertiesNested object properties

GET service

For GET services, input properties are sent as query parameters:

{
"schema": {
"input": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name" },
"units": {
"type": "string",
"description": "Temperature units",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
},
"output": {
"type": "object",
"properties": {
"temperature": { "type": "number" },
"conditions": { "type": "string" }
}
}
}
}

Callers send: GET /weather?city=London&units=celsius

POST service

For POST services, input properties are sent as a JSON body:

{
"schema": {
"input": {
"type": "object",
"properties": {
"text": { "type": "string", "description": "Text to analyze" },
"language": { "type": "string", "description": "ISO language code" }
},
"required": ["text"]
},
"output": {
"type": "object",
"properties": {
"sentiment": { "type": "string" },
"score": { "type": "number" }
}
}
}
}

Callers send: POST /sentiment with body {"text": "Hello world", "language": "en"}

Array and nested types

{
"schema": {
"input": {
"type": "object",
"properties": {
"symbols": {
"type": "array",
"items": { "type": "string" },
"description": "List of token symbols"
}
},
"required": ["symbols"]
},
"output": {
"type": "object",
"properties": {
"prices": {
"type": "array",
"items": {
"type": "object",
"properties": {
"symbol": { "type": "string" },
"price": { "type": "number" }
}
}
}
}
}
}
}
Backward Compatibility

The legacy queryParams, body, and input schema fields are still accepted for existing endpoints. New services should use the JSON Schema input/output format described above.