{"version":2,"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","payTo":"0x8eCbd65228930060363C70854da7D37D57ffC358","paymentFailures":{"402":"Payment required, or a payment that might succeed on retry (bad signature, spent nonce, a balance we couldn't read). Carries the priced challenge in the PAYMENT-REQUIRED header.","422":"insufficient_funds — the payer wallet's on-chain USDC balance is below the quoted price. Terminal: no accepts[], and an identical retry fails identically. Fund the wallet first. Body names balance_usdc, required_usdc, shortfall_usdc."},"resources":[{"method":"GET","path":"/catalog","note":"Paid discovery: 0.01 USDC per call. Returns full SKU table."},{"method":"POST","path":"/rent","note":"Per-SKU price quoted in 402. Settled only when the box is reachable on TCP :22."},{"method":"GET","path":"/instance/{id}?token={root_token}","note":"Free. THE endpoint that returns SSH credentials, ipv4 and a paste-ready ssh command. root_token comes from your POST /rent response. Poll until phase=ready."},{"method":"GET","path":"/rentals","note":"Free. Every rental the signing wallet paid for, with expiry and renewal price vs. balance. 402 identification challenge (1 base unit) that is never settled — sign it and resend."},{"method":"GET","path":"/rentals/{id}","note":"Free, no token. Lifecycle status plus ipv4 once the box boots. Credentials are not here — use /instance."},{"method":"POST","path":"/rentals/{id}/renew?token=…&periods=N","note":"Token-gated. Extends expires_at by N periods (stack cap 1–12). Same SKU price × periods. Send periods at most once — conflicting duplicates and out-of-range values are both refused with 400, never guessed or clamped. The 200 echoes the periods applied."},{"method":"GET","path":"/regions","note":"Free. Where each region code puts a box, how precisely that is pinned (`precision`: city / country / area), and its per-month surcharge. Read before buying a non-default region."},{"method":"POST","path":"/feedback","note":"Free, no auth. POST raw markdown or JSON {message, rental_id?, token?, contact?}. Goes to a human."}],"openapi":"https://vps.phoneagent.xyz/openapi.json"}