SDK API Reference
This reference documents the public APIs behind Avery SDK agent payment tools and direct x402 paid HTTP calls.
All public SDK APIs are exported from @averyso/alpha. Do not import from packages/sdk/src/... paths.
No Avery account is required for payment features. The package is installed and imported as @averyso/alpha, but runtime payment execution uses local x402 signing with your configured wallet/private key, RPC URL, and target x402 endpoint. Provider-side settlement may happen locally or through the provider's facilitator, but Avery SDK does not configure that path. You do not need an Avery account, Avery API key, Avery-hosted service, or registration.
import {
X402Client,
X402ConfigError,
X402Error,
X402Networks,
X402PaymentError,
resolveX402Network,
x402MastraTool,
x402tool,
} from "@averyso/alpha";X402Client
Pays and calls x402-protected HTTP endpoints.
const client = new X402Client(process.env.X402_PRIVATE_KEY!, {
network: X402Networks.baseSepolia,
rpcUrl: process.env.X402_RPC_URL,
});Constructor signature:
new X402Client(privateKey, options);For EVM networks, privateKey must be a 32-byte hex string. It can include or omit the 0x prefix. For Solana networks, privateKey must be a base58-encoded 64-byte Solana secret key.
X402ClientOptions
interface X402ClientOptions {
network: X402NetworkInput;
logLevel?: LogLevel;
logger?: Logger;
fetch?: typeof fetch;
maxAmount?: bigint;
rpcUrl?: string;
}network: Required x402 network. AcceptsX402Networksconstants, friendly names, primary slugs, or raw CAIP-2Networkstrings.logLevel: Minimum level for the default logger. Defaults to"info".logger: Custom diagnostic logger withdebug,info,warn, anderrormethods. For adapter examples and audit logging guidance, see Observability and Audit Logging.fetch: Custom fetch implementation. If neither this norglobalThis.fetchis available, the constructor throwsX402ConfigError.maxAmount: Default per-payment cap. Defaults to100000n. It is the fallback cap when a direct call or tool does not provide a more specific cap.rpcUrl: Optional RPC URL passed to the payment scheme.
There is intentionally no facilitator option. X402ClientOptions configures the buyer-side wallet, network, cap, fetch, logging, and RPC behavior. The resource server controls its accepted assets, payment scheme, pricing, and provider-side settlement path.
The maxAmount value is an atomic-unit cap, not a decimal string or a user/session/day budget. For budget ledger patterns, see Agent Spend Controls.
Network Selection
new X402Client(process.env.X402_PRIVATE_KEY!, {
network: "Base Sepolia",
});
new X402Client(process.env.X402_PRIVATE_KEY!, {
network: X402Networks.baseSepolia,
});
resolveX402Network("base-sepolia"); // "eip155:84532"client.network always returns normalized CAIP-2, so new X402Client(key, { network: "Base Sepolia" }).network is "eip155:84532". Existing raw CAIP-2 inputs such as "eip155:84532" continue to work.
Friendly names, primary slugs, and built-in aliases are matched case-insensitively after trimming and collapsing whitespace. Raw eip155:* CAIP-2 values pass through for compatibility. Raw Solana CAIP-2 values must be one of the supported Solana entries in the table below.
const X402Networks: {
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
base: "eip155:8453";
polygon: "eip155:137";
xLayer: "eip155:196";
peaq: "eip155:3338";
sei: "eip155:1329";
skaleBase: "eip155:1187947933";
kiteAI: "eip155:2366";
arbitrum: "eip155:42161";
solanaDevnet: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
baseSepolia: "eip155:84532";
avalancheFuji: "eip155:43113";
polygonAmoy: "eip155:80002";
xLayerTestnet: "eip155:1952";
seiTestnet: "eip155:713715";
skaleBaseSepolia: "eip155:324705682";
arbitrumSepolia: "eip155:421614";
};
type X402NetworkInput = X402NetworkName | X402NetworkSlug | Network | string;
function resolveX402Network(input: X402NetworkInput): Network;Built-in friendly names and primary slugs:
| Friendly Name | Primary Slug | CAIP-2 |
|---|---|---|
Solana Mainnet | solana | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp |
Base Mainnet | base | eip155:8453 |
Polygon Mainnet | polygon | eip155:137 |
xLayer Mainnet | xlayer | eip155:196 |
Peaq Mainnet | peaq | eip155:3338 |
Sei Mainnet | sei | eip155:1329 |
SKALE Base | skale-base | eip155:1187947933 |
KiteAI Mainnet | kiteai | eip155:2366 |
Arbitrum One | arbitrum | eip155:42161 |
Solana Devnet | solana-devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 |
Base Sepolia | base-sepolia | eip155:84532 |
Avalanche Fuji | avalanche-fuji | eip155:43113 |
Polygon Amoy | polygon-amoy | eip155:80002 |
xLayer Testnet | xlayer-testnet | eip155:1952 |
Sei Testnet | sei-testnet | eip155:713715 |
SKALE Base Sepolia | skale-base-sepolia | eip155:324705682 |
Arbitrum Sepolia | arbitrum-sepolia | eip155:421614 |
Properties
client.network;
client.maxAmount;network: The configured network as normalized CAIP-2Network.maxAmount: The client default payment cap.
call(endpoint, init?, opts?)
const result = await client.call(
"https://api.example.com/weather",
{ query: { city: "Tokyo" } },
{ maxAmount: 50_000n },
);By default, call() resolves to EndpointResult. With throwOnError: true, failed results throw X402PaymentError.
await client.call(
"https://api.example.com/weather",
{ query: { city: "Tokyo" } },
{ throwOnError: true },
);interface X402CallOptions {
signal?: AbortSignal;
maxAmount?: bigint;
throwOnError?: boolean;
}maxAmount can be set on the client, the individual call, or an x402tool(). The more specific value wins: direct client.call() options override the client default, and an x402tool() maxAmount is passed to the tool's internal client.call(). For a production policy model around these caps, see Agent Spend Controls.
x402tool(config)
Creates a Vercel AI SDK ToolSet-compatible tool backed by an x402 endpoint.
import { jsonSchema } from "ai";
import { X402Client, X402Networks, x402tool } from "@averyso/alpha";
const client = new X402Client(process.env.X402_PRIVATE_KEY!, {
network: X402Networks.baseSepolia,
rpcUrl: process.env.X402_RPC_URL,
});
const tools = {
getWeather: x402tool<{ city: string }>({
client,
description: "Get current weather for a city.",
inputSchema: jsonSchema({
type: "object",
properties: {
city: { type: "string" },
},
required: ["city"],
additionalProperties: false,
}),
endpoint: "https://api.example.com/weather",
maxAmount: 50_000n,
}),
};endpoint can be static:
x402tool({
client,
inputSchema,
endpoint: "https://api.example.com/weather",
});or dynamic:
x402tool<{ city: string }>({
client,
inputSchema,
endpoint: (input) => ({
url: "https://api.example.com/weather",
query: { city: input.city },
}),
});When request is not provided, tool input is mapped automatically:
GET,HEAD, andDELETEplain object input is added to the query string.POST,PUT, andPATCHinput is sent as a JSON body.
When request is provided, automatic input mapping is disabled:
x402tool<{ prompt: string }>({
client,
inputSchema,
endpoint: "https://api.example.com/summarize",
request: (input) => ({
method: "POST",
body: { text: input.prompt },
}),
});Without execute, the tool returns EndpointResult. With execute, the function receives { endpoint, input } and can return a model-friendly value:
x402tool<{ city: string }, { forecast: unknown }>({
client,
inputSchema,
endpoint: "https://api.example.com/weather",
execute: ({ endpoint }) => ({
forecast: endpoint.kind === "success" ? endpoint.body : null,
}),
});X402ToolConfig
type X402ToolConfig<INPUT, OUTPUT = EndpointResult> = {
client: X402Client;
endpoint: EndpointInput | ((input: INPUT) => EndpointInput);
request?: (
input: INPUT,
) =>
| EndpointRequestInit
| EndpointConfig
| undefined
| PromiseLike<EndpointRequestInit | EndpointConfig | undefined>;
maxAmount?: bigint;
throwOnError?: boolean;
execute?: (
context: { endpoint: EndpointResult; input: INPUT },
options: X402ToolExecutionOptions,
) => OUTPUT | PromiseLike<OUTPUT>;
};The config also accepts the AI SDK-style tool fields implemented by X402Tool, including description, title, inputSchema, outputSchema, needsApproval, strict, and streaming input callbacks. Use needsApproval to pause high-risk or user-visible paid tool calls for application or human authorization. See Agent Spend Controls for approval and confirmation patterns.
X402ToolExecutionOptions
interface X402ToolExecutionOptions {
toolCallId: string;
messages: unknown[];
abortSignal?: AbortSignal;
experimental_context?: unknown;
}These options are passed through from the AI SDK tool execution context.
x402MastraTool(config)
Creates a Mastra createTool()-compatible tool backed by an x402 endpoint. Use this helper for Mastra agents. Use x402tool() for Vercel AI SDK ToolSet integrations.
import { z } from "zod";
import { X402Client, X402Networks, x402MastraTool } from "@averyso/alpha";
const client = new X402Client(process.env.X402_PRIVATE_KEY!, {
network: X402Networks.baseSepolia,
rpcUrl: process.env.X402_RPC_URL,
});
const paidWeather = x402MastraTool({
id: "paid-weather",
client,
description: "Get current weather for a city from a paid x402 endpoint.",
inputSchema: z.object({
city: z.string(),
}),
endpoint: "https://api.example.com/weather",
maxAmount: 50_000n,
execute: ({ endpoint }) => ({
ok: endpoint.ok,
weather: endpoint.ok ? endpoint.body : null,
}),
});x402MastraTool() does not import @mastra/core at runtime and does not add Mastra as a dependency of Avery SDK. Your application installs and runs Mastra; the helper returns a structurally compatible Mastra tool object with Mastra's tool marker.
X402MastraToolConfig
type X402MastraToolConfig<INPUT, OUTPUT = EndpointResult, ID extends string = string> = {
id: ID;
description: string;
inputSchema: unknown;
outputSchema?: unknown;
client: X402Client;
endpoint: EndpointInput | ((input: INPUT) => EndpointInput);
request?: (
input: INPUT,
) =>
| EndpointRequestInit
| EndpointConfig
| undefined
| PromiseLike<EndpointRequestInit | EndpointConfig | undefined>;
maxAmount?: bigint;
throwOnError?: boolean;
execute?: (
context: { endpoint: EndpointResult; input: INPUT },
options: X402MastraToolExecutionContext,
) => OUTPUT | PromiseLike<OUTPUT>;
};The config also accepts Mastra tool fields including requireApproval, strict, providerOptions, toModelOutput, transform, inputExamples, mcp, mcpMetadata, requestContextSchema, suspendSchema, and resumeSchema.
The endpoint, request override, automatic input mapping, maxAmount, and throwOnError behavior matches x402tool(). Without execute, the tool returns EndpointResult. With execute, return a smaller model-friendly shape instead of exposing the full payment and HTTP result to the model.
X402MastraToolExecutionContext
interface X402MastraToolExecutionContext {
abortSignal?: AbortSignal;
toolCallId?: string;
messages?: unknown[];
requestContext?: unknown;
workspace?: unknown;
[key: string]: unknown;
}Mastra passes this context to the tool. Avery SDK uses abortSignal for the underlying x402 HTTP request and passes the whole object to your execute mapper.
When registering tools with a Mastra Agent, Mastra stream toolName values come from the object key, not the tool id:
tools: {
paidWeather, // toolName: "paidWeather"
[paidWeather.id]: paidWeather, // toolName: "paid-weather"
}Endpoint Types
EndpointConfig
interface EndpointConfig {
url: string | URL;
method?: EndpointMethod | Lowercase<EndpointMethod> | string;
headers?: HeadersInput;
query?: URLSearchParams | Record<string, unknown>;
body?: RequestBody | JsonValue;
}Use EndpointConfig when you want the endpoint itself to carry method, headers, query, or body defaults.
EndpointInput
type EndpointInput = string | URL | EndpointConfig;Accepted by X402Client.call() and x402tool() endpoint configuration.
EndpointRequestInit
interface EndpointRequestInit extends Omit<RequestInit, "body" | "headers" | "method"> {
method?: EndpointMethod | Lowercase<EndpointMethod> | string;
headers?: HeadersInput;
query?: URLSearchParams | Record<string, unknown>;
body?: RequestBody | JsonValue;
}Use this as the second argument to client.call() or as the value returned by an x402tool() request function.
EndpointResult
EndpointResult is a discriminated union keyed by kind. For lifecycle-level interpretation of each kind, see Concepts. For retry and user-facing handling strategies, see Error Handling.
const result = await client.call("https://api.example.com/weather");
if (result.kind === "success") {
console.log(result.paymentResponse, result.body);
}Kinds:
success: The endpoint was paid and returned a successful settled response.settle_failed: Payment settlement failed after the endpoint response.payment_required: The endpoint required payment, but no compatible payment was completed.error: The endpoint or x402 payment flow failed.passthrough: The response did not require payment and was returned without a payment response.
Every variant includes:
interface EndpointResultMetadata {
url: string;
method: string;
status: number;
statusText: string;
headers: Record<string, string>;
}The union also exposes ok, paid, status, body, paymentResponse, and metadata. Narrow on kind before reading payment-specific fields.
Errors
For production error handling, retry strategy, and safe model-facing tool outputs, see Error Handling.
X402Error
Base class for x402 SDK errors.
try {
await client.call("https://api.example.com/weather", undefined, {
throwOnError: true,
});
} catch (error) {
if (error instanceof X402Error) {
console.error(error.details);
}
}X402ConfigError
Thrown when the SDK cannot be configured, including invalid private keys, unsupported network inputs, unsupported Solana CAIP-2 networks, or missing fetch.
X402PaymentError
Thrown for paid endpoint failures when throwOnError: true is set. It includes status and optional details.
if (error instanceof X402PaymentError) {
console.error(error.status, error.details);
}X402ErrorDetails
interface X402ErrorDetails {
cause?: unknown;
[key: string]: unknown;
}Used by X402Error, X402ConfigError, and X402PaymentError.
Logging
Logger
interface Logger {
debug(message: string, details?: Record<string, unknown>): void;
info(message: string, details?: Record<string, unknown>): void;
warn(message: string, details?: Record<string, unknown>): void;
error(message: string, details?: Record<string, unknown>): void;
}LogLevel
type LogLevel = "debug" | "info" | "warn" | "error" | "silent";Pass logger and logLevel to X402ClientOptions.
The SDK logger is diagnostic. It does not include the application context needed for a complete spend audit trail, such as user id, conversation id, approval decision, and budget reservation id. See Observability and Audit Logging for logger adapters and audit event patterns.
x402 Core Types
Network
Re-exported from @x402/core/types. Raw CAIP-2 strings remain supported for backwards compatibility. Unknown friendly names and unsupported raw Solana CAIP-2 values throw X402ConfigError with details.network and details.supportedNetworks.
SettleResponse
Re-exported from @x402/core/types. Successful and settlement-failed endpoint results include a paymentResponse: SettleResponse.
CommonJS
The package also supports CommonJS consumers:
const { X402Client, x402tool } = require("@averyso/alpha");