Metered API Access

Metered API Access

Pay for any x402 API with a simple API key — no wallets, no signing, no crypto in your code. Think of it as Stripe for x402 buyers.

How it works: You get an API key + custodial wallets. Fund the wallets with USDC, then make HTTP requests through the proxy. When the target API returns 402, the proxy signs and submits payment automatically from your wallet and returns the API response.

Quick Start

1Create an API Key

Go to Dashboard → Metered API Access and click "New Key". This creates:

  • An API key (prefix: rpx_)
  • A Solana custodial wallet (for Solana x402 APIs)
  • An EVM custodial wallet (for Base, SKALE Base, Avalanche APIs)

Or via API:

curl -X POST https://api.relai.fi/metered/register \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"label": "My App"}'
Response example
{
  "apiKey": "rpx_a1b2c3d4e5f6...",
  "label": "My App",
  "wallets": {
    "solana": {
      "address": "4KuwK7vPceo...",
      "network": "solana"
    },
    "evm": {
      "address": "0x0787F752a0...",
      "networks": ["base", "skale-base", "avalanche"]
    }
  }
}

2Deposit USDC

Send USDC to the wallet addresses from step 1:

NetworkTokenSend to
SolanaUSDC (SPL)Your Solana wallet address
Base / SKALE / AvalancheUSDC (ERC-20)Your EVM wallet address
All EVM networks share the same wallet address. Deposit USDC on the specific chain you plan to use.

3Make API Calls

Call any x402 API through the proxy — payment is handled automatically:

curl "https://api.relai.fi/metered/x?url=https://api.example.com/data" \
  -H "X-API-Key: rpx_your_key_here"

The proxy forwards your request, detects 402, signs payment from your wallet, retries with payment proof, and returns the API response.

API Reference

Authentication

Two auth methods depending on the endpoint:

EndpointsAuthHeader
register, keys, deleteJWT BearerAuthorization: Bearer <JWT>
balance, usage, proxyAPI KeyX-API-Key: rpx_...
POST/metered/register

Create a new API key with custodial wallets. Max 5 keys per user.

Request Body

{ "label": "My App" }  // optional

Response 201

{
  "apiKey": "rpx_...",
  "label": "My App",
  "wallets": {
    "solana": { "address": "...", "network": "solana" },
    "evm": { "address": "...", "networks": ["base", "skale-base", "avalanche"] }
  },
  "depositInstructions": "..."
}
GET/metered/keys

List all API keys for the authenticated user. Secrets are never returned.

Response

{
  "keys": [{
    "apiKey": "rpx_...",
    "label": "My App",
    "active": true,
    "wallets": { "solana": { "address": "..." }, "evm": { "address": "..." } },
    "spendingLimitUsd": null,
    "createdAt": "2026-02-09T12:00:00.000Z"
  }]
}
DELETE/metered/keys/:apiKey

Revoke an API key immediately.

Response

{ "success": true }
PATCH/metered/keys/:apiKey

Update key settings — label and spending limits. All fields optional.

Request Body

{
  "maxPerTransactionUsd": 5.00,
  "maxPerPeriodUsd": 50.00,
  "periodType": "daily"
}
FieldTypeDescription
maxPerTransactionUsdnumber | nullMax USDC per single payment. null = unlimited
maxPerPeriodUsdnumber | nullMax total USDC per period. null = unlimited
periodTypestringdaily, weekly, or monthly
labelstringKey label

Response

{ "success": true, "updated": { "maxPerTransactionUsd": 5.00, "maxPerPeriodUsd": 50.00 } }
GET/metered/balance

Check USDC balance across all networks. Auth: X-API-Key

Response

{
  "totalBalance": 10.50,
  "balances": {
    "solana": { "address": "...", "balance": 5.00, "network": "solana" },
    "base": { "address": "...", "balance": 3.50, "network": "base" },
    "skale-base": { "address": "...", "balance": 2.00, "network": "skale-base" },
    "avalanche": { "address": "...", "balance": 0.00, "network": "avalanche" }
  }
}
GET/metered/usage

Spending summary and recent request logs. Auth: X-API-Key

Response

{
  "totalSpentUsd": 1.25,
  "totalRequests": 42,
  "recentLogs": [{
    "targetUrl": "https://api.example.com/data",
    "network": "base",
    "amountUsd": 0.01,
    "status": 200,
    "createdAt": "2026-02-09T12:30:00.000Z"
  }]
}
POST/metered/keys/:apiKey/withdraw

Withdraw USDC from a custodial wallet to an external address.

Request Body

{
  "network": "solana",
  "toAddress": "4KuwK7vPceojCsmeq...",
  "amount": 5.00
}

Response

{
  "success": true,
  "txHash": "5xY9...",
  "explorerUrl": "https://solscan.io/tx/5xY9...",
  "amount": 5.00,
  "network": "solana",
  "toAddress": "4KuwK7vP..."
}
POST/metered/keys/:apiKey/export-key

Export private keys for the custodial wallets. Handle with extreme care.

Response

{
  "wallets": {
    "solana": {
      "address": "4KuwK7vP...",
      "privateKey": "[1,2,3,...]",
      "format": "JSON array (paste into Phantom/Solflare)"
    },
    "evm": {
      "address": "0x0787F7...",
      "privateKey": "0xabc123...",
      "format": "Hex (paste into MetaMask)"
    }
  }
}
ALL/metered/x?url=<target>

The core proxy endpoint. Forwards any HTTP request to the target URL and handles x402 payment automatically.

ParamRequiredDescription
urlYesTarget x402 API URL
X-API-KeyYesYour Metered API Access key

Supports: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. All headers and body are forwarded to the target. Response includes X-Proxy: RelAI-BuyerProxy header.

# GET request
curl "https://api.relai.fi/metered/x?url=https://api.example.com/data" \
  -H "X-API-Key: rpx_..."

# POST with body
curl -X POST "https://api.relai.fi/metered/x?url=https://api.example.com/submit" \
  -H "X-API-Key: rpx_..." \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Hello"}'

Integration Examples

JavaScript / Node.js

const PROXY = "https://api.relai.fi/metered/x";
const KEY = process.env.RELAI_PROXY_KEY;

async function callX402(url, options = {}) {
  const res = await fetch(
    `${PROXY}?url=${encodeURIComponent(url)}`,
    {
      method: options.method || "GET",
      headers: {
        "X-API-Key": KEY,
        "Content-Type": "application/json",
        ...options.headers,
      },
      body: options.body ? JSON.stringify(options.body) : undefined,
    }
  );
  return res.json();
}

// GET request
const data = await callX402("https://api.example.com/data");

// POST request with JSON body
const result = await callX402("https://api.example.com/generate", {
  method: "POST",
  body: { prompt: "Hello world", maxTokens: 100 },
});

Python

import os, requests

PROXY = "https://api.relai.fi/metered/x"
KEY = os.environ["RELAI_PROXY_KEY"]

def call_x402(url, method="GET", json=None):
    r = requests.request(
        method, PROXY,
        params={"url": url},
        headers={"X-API-Key": KEY},
        json=json,
    )
    return r.json()

# GET request
data = call_x402("https://api.example.com/data")

# POST request with JSON body
result = call_x402(
    "https://api.example.com/generate",
    method="POST",
    json={"prompt": "Hello world", "maxTokens": 100},
)

cURL

# Simple GET
curl "https://api.relai.fi/metered/x?url=https://api.example.com/data" \
  -H "X-API-Key: $RELAI_PROXY_KEY"

# POST with JSON body
curl -X POST "https://api.relai.fi/metered/x?url=https://api.example.com/submit" \
  -H "X-API-Key: $RELAI_PROXY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}'

How It Works

Your Code              RelAI Proxy             x402 API
  |                       |                       |
  |--- GET /metered/x →|                       |
  |   X-API-Key: rpx_...  |                       |
  |                        |--- GET /data --------→|
  |                        |←-- 402 Payment Req ---|
  |                        |                       |
  |                        | [Sign payment]        |
  |                        |                       |
  |                        |--- GET + X-PAYMENT --→|
  |                        |←-- 200 OK + data ----|
  |                        |                       |
  |←-- 200 OK + data -----|                       |

1. Your request is forwarded to the target URL

2. If the target returns 402, the proxy parses the PAYMENT-REQUIRED header

3. For EVM: signs an EIP-2612 permit. For Solana: signs an SPL transfer

4. Re-sends the request with X-PAYMENT header

5. Returns the final API response to you

6. Logs the payment for your usage tracking

Spending Limits

Control costs by setting spending limits per API key. Configure via the dashboard (Limits button) or the PATCH /metered/keys/:apiKey endpoint.

Per-Transaction Limit

Set maxPerTransactionUsd to reject any single x402 payment above a certain amount.

// Example: reject payments over $1.00
PATCH /metered/keys/rpx_...
{ "maxPerTransactionUsd": 1.00 }

If an API requires $2.00 and the limit is $1.00, the proxy returns 402 with error "Per-transaction limit exceeded".

Periodic Limit

Set maxPerPeriodUsd + periodType to cap total spending over a time window.

// Example: max $50/day
{ "maxPerPeriodUsd": 50.00, "periodType": "daily" }
PeriodResets at
dailyMidnight (server time)
weeklyStart of week (Sunday)
monthly1st of month

Removing Limits

Set any limit to null to remove it (unlimited):

{ "maxPerTransactionUsd": null, "maxPerPeriodUsd": null }
Limit priority: per-transaction → periodic → legacy total. A payment must pass all configured limits.

Supported Networks

NetworkTypeTokenPayment Method
SolanaSVMUSDC (SPL)Signed SPL transfer
BaseEVMUSDC (ERC-20)EIP-2612 permit
SKALE BaseEVMUSDC (bridged)EIP-2612 permit
AvalancheEVMUSDC (ERC-20)EIP-2612 permit

All EVM networks share a single custodial wallet address. Solana has its own wallet.

Error Handling

StatusMeaning
401Missing or invalid API key
402Payment failed (insufficient balance, signing error, spending limit exceeded)
400Missing url parameter or invalid URL
502Target returned 402 without valid x402 requirements, or proxy failed

Example error responses

// Spending limit exceeded
{ "error": "Spending limit exceeded", "limit": 10.00, "spent": 9.50, "required": 1.00 }

// No wallet for network
{ "error": "Cannot pay: No EVM custodial wallet available for network base",
  "targetUrl": "...", "network": "eip155:8453", "amountUsd": 0.01 }

FAQ

What happens if I don't have enough USDC?

The proxy returns a 402 error explaining which network needs funding and how much.

Can one API key work across multiple networks?

Yes. Each key comes with both Solana and EVM wallets. The proxy picks the right one automatically.

Is there a fee for using the proxy?

You only pay the x402 price set by the API. RelAI does not add any markup.

What x402 versions are supported?

Both x402 v1 and v2 payment requirements are supported.

Can I use this for non-x402 APIs?

Yes — if the target doesn't return 402, the response is forwarded directly. The proxy is transparent for non-x402 endpoints.

Are my wallet keys safe?

Private keys are stored encrypted server-side. They are never exposed through the API or dashboard.