Authentication & Payments

Proxagora uses x402 micropayments (USDC on Base) and Stripe MPP instead of API keys. No signup. No OAuth. The payment is the authorization.

Authentication & Payments

Proxagora doesn't use API keys or OAuth. Access to APIs is gated by payment.

When you call an API endpoint without payment, you get HTTP 402 with payment instructions. Attach payment proof and retry. That's the entire auth flow.

x402 — USDC on Base (Recommended)

x402 is the primary payment method. It uses USDC on Base Sepolia (testnet) or Base mainnet (production).

Flow

  1. Call POST /api/{id} without payment header
  2. Receive HTTP 402 with payment spec:
{
  "x402Version": 1,
  "accepts": [{
    "scheme": "exact",
    "network": "base-sepolia",
    "maxAmountRequired": "1000",
    "resource": "https://proxagora.com/api/ip-geo",
    "description": "IP geolocation lookup",
    "mimeType": "application/json",
    "payTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
    "maxTimeoutSeconds": 300,
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
  }]
}
  1. Send USDC transfer to payTo address on specified network
  2. Encode payment proof in X-Payment header (base64 JSON)
  3. Retry original request — data returned

Network Addresses

| Network | USDC Contract | Chain ID | |---------|---------------|----------| | Base Sepolia (testnet) | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | 84532 | | Base Mainnet | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 8453 |

Using the x402 Library

pip install x402
from x402.client import X402Client
from x402.wallet import LocalWallet

wallet = LocalWallet(private_key="0x_your_key")
client = X402Client(wallet=wallet)

# Handles 402 flow automatically
response = client.post(
    "https://proxagora.com/api/ip-geo",
    json={"ip": "8.8.8.8"}
)
npm install x402
import { wrapFetchWithPayment } from 'x402'
import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const fetch = wrapFetchWithPayment(globalThis.fetch, account)

const response = await fetch('https://proxagora.com/api/ip-geo', {
  method: 'POST',
  body: JSON.stringify({ ip: '8.8.8.8' })
})

Manual Payment Header

If building your own client, the X-Payment header is base64-encoded JSON:

{
  "x402Version": 1,
  "scheme": "exact",
  "network": "base-sepolia",
  "payload": {
    "signature": "0x_transaction_hash",
    "authorization": {
      "from": "0x_your_wallet_address",
      "to": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
      "value": "1000",
      "validAfter": "0",
      "validBefore": "1749000000",
      "nonce": "0x_transaction_hash"
    }
  }
}

Encode as: base64(JSON.stringify(payload))

Stripe MPP — Card Payments

For developers who prefer card payments or don't have a Base wallet set up.

Flow

  1. Create a Stripe MPP session with a balance top-up
  2. Get a session token
  3. Use X-MPP-Payment: <token> on API calls
  4. Each call deducts from the session balance
# Create MPP session
curl -X POST https://proxagora.com/api/pay \
  -H "Content-Type: application/json" \
  -d '{"amount_usd": 10.00, "provider": "stripe"}'

# Response: { "session_token": "mpp_...", "balance_usd": 10.00 }
# Use on calls
curl -X POST https://proxagora.com/api/ip-geo \
  -H "Content-Type: application/json" \
  -H "X-MPP-Payment: mpp_..." \
  -d '{"ip": "8.8.8.8"}'

When to Use Each Method

| Scenario | Recommended | |----------|-------------| | Autonomous agent in production | x402 | | Agent testing on Base Sepolia | x402 | | Developer exploratory testing | Stripe MPP | | Team without crypto setup | Stripe MPP | | High-frequency pipelines | x402 (lower overhead) |

Getting Test USDC

For Base Sepolia testing:

  1. Get test ETH from Base Sepolia Faucet
  2. Get test USDC from Circle Faucet
  3. Set network to Base Sepolia (chain ID 84532) in your wallet

Your wallet needs both ETH (for gas) and USDC (for payments). Typical gas cost per payment: ~$0.001 in test ETH.

Payment Validation

Proxagora validates payments by:

  1. Checking the transaction hash exists on-chain
  2. Verifying recipient address matches the payTo from the 402 spec
  3. Verifying amount matches maxAmountRequired
  4. Checking transaction is confirmed (at least 1 block)
  5. Checking validBefore timestamp hasn't expired

Failed validation returns HTTP 402 again with a reason in the response body.

Overviewx402 Protocol