Protocol guide
x402 Agent Payments
Kilawatt Cloud supports x402, an open protocol for machine-to-machine payments built on the standard HTTP 402 Payment Required status code. Autonomous agents can pay for GPU compute directly from their own wallet, per request, with no account, no API key provisioning, and no human approval step.
This is a separate access path from Kilawatt's standard prepay wallet tiers (Starter, Pro, Scale). Both paths lead to the same underlying compute infrastructure; x402 is designed for agents and automated systems that want to pay as they go.
Protocol overview
How it works
x402 follows a four-step request/response cycle, all within a single logical transaction:
- 1
Agent sends a request to a Kilawatt x402 endpoint describing the compute it wants.
- 2
Kilawatt responds 402 Payment Required, returning the exact price and payment details needed to proceed.
- 3
Agent signs a payment for that exact amount from its own wallet and resends the request with payment attached.
- 4
Kilawatt verifies and settles the payment, then provisions the requested compute and returns 200 OK with job details.
No prior signup, API key, or account creation is required for any of these steps. The agent only needs a funded wallet on Base holding USDC.
Endpoint
The x402 exec route
All x402 jobs are dispatched through a single endpoint:
POST https://www.kilawattcloud.dev/api/public/x402/execStep 1
Initial request
Send a POST request describing the compute job. No payment header is included on the first attempt.
{
"gpu_type": "nvidia-a10",
"card_count": 1,
"duration_seconds": 60,
"routing_policy": "lowest_cost",
"workload_type": "agent_exec"
}| Field | Description |
|---|---|
| gpu_type(string) | GPU model to provision (e.g. nvidia-a10, nvidia-h200) |
| card_count(integer) | Number of GPU cards requested |
| duration_seconds(integer) | Requested job duration in seconds |
| routing_policy(string) | How Kilawatt selects a provider. lowest_cost is supported. |
| workload_type(string) | Job classification, e.g. agent_exec |
Step 2
Payment challenge
If no valid payment is attached, Kilawatt responds with 402 Payment Required and a JSON body describing exactly what payment will satisfy the request.
{
"x402Version": 1,
"accepts": [
{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "40000",
"resource": "https://www.kilawattcloud.dev/api/public/x402/exec",
"description": "Kilawatt GPU compute: 1x nvidia-a10 for 60s",
"mimeType": "application/json",
"payTo": "0x...",
"maxTimeoutSeconds": 120,
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"extra": {
"name": "USD Coin",
"version": "2"
}
}
]
}| Field | Description |
|---|---|
| network | Settlement network. Currently base. |
| maxAmountRequired | Price in the asset's smallest unit (USDC uses 6 decimals - 40000 = $0.04). |
| payTo | Wallet address to pay. Always read this from the live response; do not hardcode it. |
| asset | Contract address of the payment asset. Currently USDC on Base (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913). |
| maxTimeoutSeconds | Time window to complete payment before the challenge expires. |
Pricing is calculated dynamically from Kilawatt's live GPU rate card at request time. It is not a fixed value and will vary by GPU type, card count, and duration.
Step 3
Signed payment and retry
The agent's wallet signs an EIP-3009 transferWithAuthorization payload for the exact amount requested, and resends the original request with the payment attached per the x402 spec.
In practice, most implementations use an x402-aware HTTP client that handles this automatically rather than constructing the payload by hand.
Step 4
Settlement and response
Once payment is verified and settled on-chain, Kilawatt provisions the requested compute and responds 200 OK.
{
"id": "zin8f0j658jyar",
"provider": "Node US-East-04",
"workload_type": "agent_exec",
"gpu_type": "nvidia-a10",
"card_count": 1,
"routing_policy": "lowest_cost",
"failover_from": [],
"billed_usd": 0.041625,
"status": "running",
"payment": {
"transaction_hash": "0x...",
"network": "base",
"amount_usd": 0.04,
"payer": "0x...",
"stripe_payment_intent": "pi_..."
},
"api_key": "kw_live_..."
}A one-time API key is issued on successful settlement, scoped to the resulting job. Store it immediately — it is not retrievable again after this response.
| Field | Description |
|---|---|
| status | Current job status (running, etc.) |
| billed_usd | Actual amount billed, which may differ slightly from the challenge estimate |
| payment.transaction_hash | On-chain settlement transaction, verifiable on BaseScan |
| payment.stripe_payment_intent | Internal payment reference |
| api_key | One-time credential for interacting with the provisioned job |
Failure modes
Errors
If payment verification or settlement fails, Kilawatt returns a non-200 status with the same challenge structure and an error field describing the failure reason.
{
"x402Version": 1,
"error": "invalid_payload: contract call failed: unable to call contract: execution reverted",
"accepts": [ ... ]
}Common causes include insufficient token balance, insufficient network gas, or a malformed payment payload. The accepts array is included on error responses so a client can inspect requirements and retry.
Example
Reference implementation (Node.js)
This example uses Coinbase's CDP SDK for wallet signing, viem for the wallet client, and x402-fetch to handle the challenge/retry cycle automatically.
import { CdpClient } from "@coinbase/cdp-sdk";
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { wrapFetchWithPayment } from "x402-fetch";
const cdp = new CdpClient({
apiKeyId: process.env.CDP_API_KEY_ID,
apiKeySecret: process.env.CDP_API_KEY_SECRET,
});
const account = await cdp.evm.getAccount({ address: process.env.WALLET_ADDRESS });
const walletClient = createWalletClient({
account,
chain: base,
transport: http(),
});
const fetchWithPayment = wrapFetchWithPayment(fetch, walletClient);
const response = await fetchWithPayment(
"https://www.kilawattcloud.dev/api/public/x402/exec",
{
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
gpu_type: "nvidia-a10",
card_count: 1,
duration_seconds: 60,
routing_policy: "lowest_cost",
workload_type: "agent_exec",
}),
}
);
const data = await response.json();
console.log(data);The wallet used must hold USDC on Base for the payment itself, and a small amount of ETH on Base to cover network gas.
Access models
Relationship to prepay wallet tiers
x402 and Kilawatt's standard API (Starter / Pro / Scale prepay tiers) both provision the same underlying GPU infrastructure and both enforce full payment before any job is dispatched. They differ only in how payment is established.
| Feature | Prepay tiers | x402 |
|---|---|---|
| Account required | Yes | No |
| Payment timing | Deposit upfront drawn down per job | Paid per individual request |
| Best suited for | Ongoing usage / dashboard access | Autonomous agents / one-off or sporadic usage |
Notes
Implementation notes
- x402 settlement occurs via Coinbase's facilitator on Base mainnet. Transactions are publicly verifiable on-chain.
- Payment amounts are calculated from Kilawatt's live rate card at request time, inclusive of applicable margin.
- This document describes the protocol as currently implemented. Supported GPU types, networks, and assets may expand over time.
