Skip to main content

Documentation

Everything you need to integrate AgentPay into your AI agent or register your API as a provider.

Quick Start

Get your AI agent calling APIs in under 5 minutes.

1. Install the SDK

bash
pip install agentpay
# or for TypeScript:
npm install agentpay

2. Set up your Solana keypair

AgentPay uses your Solana keypair for signing payments. On devnet you can use the Solana CLI default keypair.

bash
solana-keygen new --outfile ~/.config/solana/id.json
solana airdrop 1  # devnet SOL for tx fees

3. Get devnet USDC

Each call costs USDC. On devnet you can use the SPL faucet:

bash
# Visit https://spl-token-faucet.com and request devnet USDC
# or use our helper:
python -m agentpay fund-devnet

4. Make your first paid call

python
from agentpay import AgentPay

ap = AgentPay(network="devnet")

# Discover APIs
apis = ap.discover(query="weather")
print(apis[0])  # { slug, name, price_usdc, ... }

# Call & pay automatically
result = ap.call("weather-v1", {"city": "Karachi"})
print(result)  # { temp: 34, condition: "Sunny", ... }

The SDK handles the entire 402 challenge → on-chain pay → retry flow. You just call .call().

Payment Flow

AgentPay uses HTTP 402 Payment Required as a machine-readable payment challenge.

1

Initial request

Agent sends a normal HTTP request to the gateway URL with X-Agent-Wallet header.

2

402 challenge

Gateway responds with nonce, USDC amount, recipient wallet, and expiry timestamp.

3

On-chain payment

SDK builds a USDC SPL transfer with the nonce embedded in a Memo instruction.

4

Verification + proxy

Gateway verifies the tx on-chain, checks replay nonce, then forwards to provider API.

5

Response returned

Provider response is forwarded back. Usage is logged for hourly settlement.

402 challenge response

http
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment-Nonce: 0x9f2c…a8e3
X-Payment-Amount: 300
X-Payment-Currency: USDC-DEVNET
X-Payment-Recipient: 7xKX…m3Pq
X-Payment-Expires: 1746800000

{
  "challenge": {
    "nonce": "0x9f2c…a8e3",
    "amount_usdc_micro": 300,
    "recipient": "7xKX…m3Pq",
    "memo_template": "agentpay:0x9f2c…a8e3",
    "expires_at": 1746800000
  }
}

Authentication

Two distinct authentication mechanisms operate inside AgentPay:

1. Agents — wallet signatures (no auth at all)

Agents do not authenticate. They prove they paid by including a confirmed Solana transaction signature on the retry request:

http
POST /api/proxy/{slug}
X-Payment-Tx: 5Hq2KL...kL9n
X-Payment-Nonce: 0x9f2c…a8e3
X-Agent-Wallet: 7xKX...m3Pq

{ "your": "params" }

2. Providers — Sign-In With Solana (SIWS)

Providers authenticate to manage their APIs and read usage data. The flow:

typescript
// 1. Wallet signs a SIWS message
const message = "AgentPay wants you to sign in with your Solana account:\n" + wallet;
const signature = await wallet.signMessage(encodeUTF8(message));

// 2. POST signature to /auth/signin → JWT
const { access_token } = await fetch("/api/auth/signin", {
  method: "POST",
  body: JSON.stringify({ wallet_address, message, signature })
}).then(r => r.json());

// 3. Use JWT for /providers/me, /apis, etc.
fetch("/api/providers/me", {
  headers: { Authorization: `Bearer ${access_token}` }
});

Tokens expire after 24 hours by default. SIWS messages are not stored — only the JTI (token ID) is tracked for revocation.

Discovery API

Public endpoint for finding APIs. No auth required — your agent can call this to dynamically pick services.

http
GET /api/v1/discover?query=weather&category=weather&limit=20

Query parameters

paramtypedescription
querystring?Substring match against name/description/category
categorystring?weather · finance · scraping · llm · geo · data · other
limitintMax 100. Default 20.
offsetintPagination offset. Default 0.

Response

json
{
  "apis": [
    {
      "slug": "weather-v1",
      "name": "Weather API",
      "description": "Real-time weather data for any city",
      "category": "weather",
      "price_usdc": 0.0003,
      "price_usdc_micro": 300,
      "gateway_url": "https://agentpay.io/api/proxy/weather-v1",
      "provider": "MeteoCore"
    }
  ],
  "total": 1, "offset": 0, "limit": 20
}

SDK Reference

The Python SDK is the reference implementation. The TypeScript SDK exposes the same surface.

AgentPay()

python
AgentPay(
  network="devnet",           # "devnet" | "mainnet-beta"
  keypair_path=None,          # path to id.json
  keypair_secret=None,        # base58 secret key string
  gateway_url=None,           # override default gateway
  timeout=30.0,               # request timeout in seconds
  max_spend_usdc=None,        # safety cap per session
)

.discover()

python
apis = ap.discover(
  query="weather",
  category="weather",
  limit=20,
)
# Returns list[ApiInfo] — { slug, name, price_usdc, gateway_url, ... }

.call()

python
result = ap.call(
  slug="weather-v1",
  data={"city": "NYC"},
  method="POST",              # GET / POST / PUT / PATCH / DELETE
  max_price_usdc=0.001,       # refuses if API price exceeds this
)
# Returns parsed JSON response from the provider

Always set max_price_usdc in production agents — it's the easiest defence against a misconfigured upstream charging more than expected.

Error handling

python
from agentpay.exceptions import (
  GatewayUnavailableError,
  InsufficientFundsError,
  PaymentVerificationError,
  AgentPayError,
)

try:
    ap.call("weather-v1", {"city": "NYC"})
except InsufficientFundsError:
    # Top up devnet USDC and retry
    ...
except PaymentVerificationError:
    # Tx didn't confirm in time — usually a transient devnet issue
    ...

Becoming a Provider

Any HTTP API can be listed on AgentPay. You register the endpoint, set a price, and AgentPay handles discovery, payment, and settlement.

Connect your Solana wallet via the Dashboard
Fill in API name, description, base URL, and category
Enter your existing API key — AES-256 encrypted before storage
Set a per-call USDC price (min $0.0001)
Your API gets a gateway URL — agents can discover and call it immediately

How requests reach your API

When a paid agent call arrives, AgentPay forwards it to your base_url verbatim, plus your provider API key as the Authorization header. The agent's request body and method are passed through.

Settlement

A cron job runs every hour, sums unsettled usage logs per provider, deducts a 5% platform fee, and sends USDC directly to your payout_wallet. Every settlement is fully visible on Solana Explorer.

REST API

Backend endpoints exposed by the AgentPay gateway.

Method · PathAuthDescription
GET /api/v1/discoverPublic discovery
POST /api/auth/signinSIWS sign-in → JWT
POST /api/auth/signoutJWTRevoke session
GET /api/providers/meJWTCurrent provider profile
PUT /api/providers/meJWTUpdate profile + payout wallet
POST /api/providers/onboardJWTComplete onboarding
GET /api/providers/me/usageJWTUsage summary
GET /api/providers/me/usage/logsJWTUsage logs (paginated)
GET /api/providers/me/payoutsJWTSettlement history
GET /api/apisJWTList your APIs
POST /api/apisJWTRegister a new API
PATCH /api/apis/{id}JWTUpdate an API
DELETE /api/apis/{id}JWTPause an API (soft delete)
ANY /api/proxy/{slug}PaymentPaid gateway — 402 challenge protocol

Errors & Limits

HTTP error codes

CodeMeaningWhat to do
400Bad requestInspect detail field
401Invalid SIWS signature or expired JWTRe-sign in
402Payment requiredSDK handles automatically
403Forbidden — wrong wallet for this APISign in with the owning wallet
404API slug not foundConfirm the slug exists on /v1/discover
409Slug already takenChoose a different slug
429Rate limitedBack off — see Retry-After header
503API paused or upstream unavailableCheck provider status

Rate limits

Per-API rate limits are configurable by the provider (default 60 req/min). Discovery is rate-limited at 120 req/min per IP.

Replay protection

Every 402 challenge is single-use. The nonce is checked on-chain (via the Memo) and in Redis. Submitting the same tx twice returns 409 Conflict.