Developer Guide

How to Monetize Your API for AI Agents Using XRP Payment Channels

January 22, 20264 min read

AI agents are becoming significant API consumers. As autonomous programs chain calls across services to complete tasks, the traditional model of API keys and monthly subscriptions creates friction. This guide walks through adding micropayment billing to a Python API using XRP payment channels.

Prerequisites

  • Python 3.9+
  • A REST API (Flask, FastAPI, or Django)
  • An XRP testnet wallet (we'll set one up below)
  • Basic familiarity with decorators and middleware patterns

Testnet Setup

Before writing code, get a funded testnet wallet. The XRPL testnet faucet provides free test XRP:

# Get a funded testnet wallet
# Visit: https://faucet.altnet.rippletest.net/accounts
# Or use the SDK:
from clasp import create_testnet_wallet

wallet = create_testnet_wallet()
print(f"Address: {wallet.address}")
print(f"Seed: {wallet.seed}")  # Save this for configuration

The testnet mirrors mainnet behavior but with free XRP. All examples below use network="testnet" — switch to "mainnet" when you're ready for production.

Install

pip install clasp-protocol

Initialize

from clasp import CLASPServer

# Configure with your XRP address and network
sp = CLASPServer(
    xrp_address="rYourTestnetAddress...",
    network="testnet",  # Use "mainnet" for production
)

Protect Endpoints

from flask import Flask, request

app = Flask(__name__)

@app.route("/api/weather/forecast")
@sp.require_payment(price_drops=1000)  # 0.001 XRP per call
def get_forecast():
    city = request.args.get("city", "Toronto")
    return {"forecast": get_weather(city)}

@app.route("/api/translate")
@sp.require_payment(price_drops=5000)  # 0.005 XRP per call (heavier compute)
def translate():
    text = request.json["text"]
    target = request.json.get("target_lang", "en")
    return {"translation": translate_text(text, target)}

That's it. Your API now accepts CLASP micropayments. Requests without a valid payment claim receive an HTTP 402 Payment Required response with instructions.

Under the Hood

When a request arrives, the SDK does the following:

  1. Extracts the X-CLASP-Claim header (base64-encoded claim + signature)
  2. Decodes the 44-byte claim: 4-byte magic (CLM), 32-byte channel ID, 8-byte amount
  3. Verifies the ECDSA secp256k1 signature against the channel's public key
  4. Confirms the claimed amount exceeds the previous claim by at least price_drops
  5. Returns the response if valid, or 402 with payment instructions if not

No blockchain call is needed for verification. The signature check is pure cryptography, completing in under 1ms. The channel's existence and funding are verified only at channel open time.

Security Model

The cryptographic properties of payment channels provide strong guarantees:

  • Double-spend prevention: Claims are cumulative and monotonically increasing. A claim for 5,000 drops followed by a claim for 3,000 drops is invalid by definition.
  • Forgery prevention: Claims require a valid ECDSA signature from the channel's source keypair. Without the private key, claims cannot be fabricated.
  • Rate limiting: The channel has a finite deposit. Once the cumulative claims reach the channel balance, the agent must fund or open a new channel.

For additional protection, add standard rate limiting on top of payment verification:

# Optional: combine with rate limiting
@app.route("/api/expensive-operation")
@rate_limit(max_per_minute=60)  # Your rate limiter
@sp.require_payment(price_drops=10000)
def expensive_operation():
    return {"result": run_expensive_computation()}

Settlement

# Settle all open channels — one on-chain transaction each
sp.settle_all()

# Or settle a specific channel
sp.settle(channel_id="ABC123...")

Settlement submits the latest claim for each channel to the XRP Ledger. The provider receives the claimed amount; the remainder returns to the agent. Run settlement on a schedule (daily, weekly) or when channel balances reach a threshold.

Framework Compatibility

The require_payment decorator works with Flask out of the box. For other frameworks:

  • FastAPI: Use sp.fastapi_dependency(price_drops=1000) as a Depends() parameter
  • Django: Use sp.django_middleware() in your MIDDLEWARE setting
  • Express.js: Use the Node SDK: sp.requirePayment({priceDrops: 1000}) as middleware

Pricing Guide

Suggested pricing tiers based on computational cost (1 XRP = 1,000,000 drops):

Operation TypeDropsUSD Equivalent*
Simple lookups (key-value, status checks)100-500$0.0002-$0.001
Database queries (filtered, paginated)500-2,000$0.001-$0.004
Complex computation (aggregation, analysis)2,000-10,000$0.004-$0.02
LLM inference (prompt + completion)10,000-100,000$0.02-$0.20
GPU workloads (image gen, fine-tuning)50,000-500,000$0.10-$1.00

* At ~$2.00/XRP. Prices in drops remain stable; USD equivalent varies with XRP price.

Troubleshooting

  • 402 with "no claim header": The client isn't sending the X-CLASP-Claim header. Ensure the agent SDK is configured with the correct server URL.
  • 402 with "insufficient amount": The claim increment is less than price_drops. The agent's cumulative claim must increase by at least the endpoint price with each call.
  • 402 with "invalid signature": The claim signature doesn't match the channel's public key. Verify the agent is using the correct keypair for the channel.
  • Channel not found: The channel ID in the claim doesn't exist on-ledger. The agent needs to open a channel to your address first.

Next Steps

For the business case behind micropayment APIs, read From SaaS to Pay-Per-Call. For the technical comparison of payment protocols, see Stripe x402 vs XRP Payment Channels.

Full SDK documentation: symplesolutions.ca/clasp

Want to learn more about developer guide?

Get in touch →

Build with CLASP

Add micropayment billing to any API in 10 lines of code. AI agents pay per call using XRP payment channels.

See How CLASP Works Explore SympleWallet