Skip to content

Payments

Agents need a positive prepaid balance to create streams, clips, DVR recordings, and VOD uploads. Two funding methods are available: x402 (inline, instant) and crypto deposits (on-chain transfer).

x402 enables gasless USDC payments using EIP-3009 transferWithAuthorization. The agent signs a transfer authorization off-chain; FrameWorks submits it on-chain and pays the gas.

  1. Agent calls a billable tool (e.g., create_stream) with insufficient balance.
  2. Server returns an INSUFFICIENT_BALANCE error with x402_accepts payment options.
  3. Agent signs an EIP-3009 authorization for the required amount.
  4. Agent retries with the X-PAYMENT header containing the base64-encoded signed payload.
  5. Server verifies the signature, submits the transaction on-chain, and credits the balance.
  6. The original operation proceeds.

For browser-based integrations, MCP and GraphQL are CORS-readable public protocol surfaces. JavaScript clients can make the actual unauthenticated API request, receive the 402 response body, sign the payment authorization, and retry with X-PAYMENT.

Call get_payment_options (public, no auth required) to get the platform’s payment address and supported networks:

{
"x402_version": 1,
"options": [
{
"network": "base",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"asset_symbol": "USDC",
"pay_to": "0x..."
},
{
"network": "arbitrum",
"asset": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"asset_symbol": "USDC",
"pay_to": "0x..."
}
]
}

The X-PAYMENT header contains a base64-encoded JSON payload:

{
"x402Version": 1,
"scheme": "exact",
"network": "base",
"payload": {
"signature": "0x...",
"authorization": {
"from": "0x<your-wallet>",
"to": "0x<payTo-from-payment-options>",
"value": "1000000",
"validAfter": "0",
"validBefore": "1735689600",
"nonce": "0x..."
}
}
}

PAYMENT-SIGNATURE is also accepted as a header name.

NetworkChain IDUSDC Contract
Base84530x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Arbitrum421610xaf88d065e77c8cC2239327C5EDb3A432268e5831

For non-x402 prepaid top-ups, use the deposit flow:

  1. Call topup_balance with amount_cents and asset: "ETH" or "USDC".
  2. The response is a locked-rate quote: a deposit address plus the exact expected_amount_token to send (e.g. 0.01515 ETH), the quoted_price_usd it was locked at (Chainlink for ETH; 1:1 for USDC), and a 24h expires_at.
  3. Send exactly the quoted amount on-chain.
  4. Call check_topup to follow the lifecycle: pending → confirming → completed.
  5. Once confirmed, the balance is credited at the locked rate (received_token × quoted_price_usd), so you get exactly what was quoted regardless of price drift inside the 24h TTL.

LPT is not supported as a top-up asset. Chainlink doesn’t publish an official LPT/USD aggregator, so topup_balance rejects asset: "LPT".

Billable MCP tools validate positive prepaid balance before executing. Account status can also report billing detail blockers; x402 settlement enforces billing details for payments of €100 or more. When requirements aren’t met, the error includes resolution guidance:

Missing billing details:

{
"code": "BILLING_DETAILS_MISSING",
"message": "Billing details required before any payments",
"resolution": "Call update_billing_details with address_line1, city, postal_code, country",
"tool": "update_billing_details",
"required_fields": ["address_line1", "city", "postal_code", "country"]
}

Insufficient balance:

{
"code": "INSUFFICIENT_BALANCE",
"message": "Balance is 0 cents. Top up required to perform billable operations.",
"resolution": "Call topup_balance tool to add credits, OR pay via x402",
"tool": "topup_balance",
"x402_accepts": [
{ "network": "base", "asset": "USDC", "pay_to": "0x...", "description": "USDC on Base" },
{ "network": "arbitrum", "asset": "USDC", "pay_to": "0x...", "description": "USDC on Arbitrum" }
]
}

Prepaid usage deductions can move an account toward zero or negative balance. Monitor via the billing://balance resource:

FieldDescription
balance_centsCurrent balance
drain_rate_cents_per_hourRecent rated spend rate, when available
estimated_hours_leftTime until depletion
live_metricsCurrent operational usage context

At zero or below, prepaid accounts are blocked from new billable operations unless the request is settled with x402. If the balance drops below -€10, Purser suspends the tenant and asks Commodore/Foghorn to terminate active streams and sessions. Top up proactively.