Let an AI agent buy proxies: a UCP checkout paid from the balance
An AI agent can buy a proxy plan on QuanticData without a dashboard. It opens a checkout session in the Universal Commerce Protocol shape for one plan, reads the real total, and either pays it from the prepaid balance of its account or hands the person a link to pay by card, PayPal or crypto. Then it generates proxy lines with the order id.
$2 of free API usage per month · No card required · Failed calls are never billed
GET https://api.quanticdata.io/.well-known/ucp → dev.ucp.shopping.checkout · payment handler "balance" POST /v1/agent/ucp/checkout-sessions {"line_items":[{"item":{"id":"pln_…"}}]} → 201 status "ready_for_complete" · total 1200 (USD cents) · tax 0 POST /v1/agent/ucp/checkout-sessions/chk_…/complete {handler_id:"balance"} → 200 status "completed" · order.id "ord_…" POST /v1/public/proxies/generate {"orderId":"ord_…","country":"us","quantity":2} → 2 lines, sticky, same IP for 10 minutes each
How it works, in five steps
The checkout follows the UCP REST binding (capability dev.ucp.shopping.checkout, version 2026-08-25). One session holds one plan with quantity 1, because that is what one order on the dashboard holds too. The agent owns exactly one payment instrument, the prepaid balance of its account; everything else is the person's.
| Step | Call | What you keep |
|---|---|---|
| 1. Pick a plan | GET /v1/public/plans?planType=residentialpremium | plans[].id, amount (USD) |
| 2. Open a session | POST /v1/agent/ucp/checkout-sessions with the plan id and an Idempotency-Key | id, status, totals, continue_url |
| 3a. The balance covers it | POST …/checkout-sessions/{id}/complete with the balance handler | order.id |
| 3b. It does not | Give the person continue_url; poll GET …/checkout-sessions/{id} | order.id once completed |
| 4. Proxy lines | POST /v1/public/proxies/generate with orderId | proxies[] |
Totals are USD cents. VAT follows the rule of the human checkout: 0% when the session is paid from the balance or in crypto, 22% when a person pays by card or PayPal. ISP plans are configured per order and are not sold through this checkout; the Premium ISP and IPv6 endpoints or the dashboard handle them.
Step zero
Discover the checkout
The UCP profile names the service, the capability and the payment handler. It is served on the API host, the dashboard host and the site, with a public cache header.
curl -s https://api.quanticdata.io/.well-known/ucp
{
"ucp": {
"version": "2026-08-25",
"services": { "dev.ucp.shopping": [ { "transport": "rest",
"endpoint": "https://api.quanticdata.io/v1/agent/ucp" } ] },
"capabilities": { "dev.ucp.shopping.checkout": [ { "version": "2026-08-25" } ] },
"payment_handlers": { "io.quanticdata.balance": [ { "id": "balance",
"available_instruments": [ { "type": "account_balance", "currency": "USD" } ] } ] }
},
"endpoints": { "checkout_sessions": "https://api.quanticdata.io/v1/agent/ucp/checkout-sessions",
"catalog": "https://api.quanticdata.io/v1/public/plans" }
}
Pick a plan from the catalog
The catalog is the same list a person sees on the dashboard: every public plan with its id, network, gigabytes or IPs, days and list price in USD. Filter by planType (residential, residentialpremium, mobile, datacenter) and read amount; the pricing page explains what each line is for.
curl -s "https://api.quanticdata.io/v1/public/plans?planType=residentialpremium" \
-H "Authorization: Bearer $QD_API_KEY"
{ "type": "response", "payload": { "plans": [
{ "id": "pln_3e7a", "name": "Residential Premium 5 GB", "amount": 12, "bandwidth": 5, "days": 90, … },
… ] } }
# and the balance, before deciding which path to take
curl -s https://api.quanticdata.io/v1/public/balance -H "Authorization: Bearer $QD_API_KEY"
Step two
Open a session and read the real total
The session quotes the plan at list price with the VAT the declared method implies. Send an Idempotency-Key: the same key answers 200 with the session already created instead of opening another, so a retry is always safe.
curl -s -X POST https://api.quanticdata.io/v1/agent/ucp/checkout-sessions \
-H "Authorization: Bearer $QD_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-10-26-001" \
-d '{"line_items":[{"item":{"id":"pln_3e7a"},"quantity":1}],"payment_method":"BALANCE"}'
{
"id": "chk_7d3f0a9b2c4e1f6a8b9c0d1e",
"status": "ready_for_complete",
"totals": [ { "type": "subtotal", "amount": 1200 }, { "type": "total", "amount": 1200 } ],
"payment": { "instruments": [ { "handler_id": "balance", "type": "account_balance", "selected": true } ] },
"continue_url": "https://app.quanticdata.io/plans?network=RESIDENTIAL&agent_checkout=chk_…",
"messages": [ { "code": "balance_available", "content": "The account balance covers this checkout. …" },
{ "code": "vat_rule", "content": "Totals carry 0% VAT (balance or crypto). …" } ]
}
ready_for_complete means the balance covers the total; requires_escalation means it does not. A session expires after 6 hours; a different plan needs a new session (the plan of a session is locked).
Step three, path A
Pay from the balance
Completing with the balance handler runs the same purchase as POST /v1/public/purchase: the balance is charged at 0% VAT, the order and the paid invoice are created and the plan is activated in one call. A session that is already completed answers 200 with the same order, so a retry never buys twice.
curl -s -X POST https://api.quanticdata.io/v1/agent/ucp/checkout-sessions/chk_7d3f0a9b2c4e1f6a8b9c0d1e/complete \
-H "Authorization: Bearer $QD_API_KEY" -H "Content-Type: application/json" \
-d '{"payment":{"instruments":[{"handler_id":"balance","type":"account_balance","selected":true}]}}'
{
"status": "completed",
"order": { "id": "ord_8c21", "permalink_url": "https://app.quanticdata.io/proxies" },
"messages": [ { "code": "order_created", "content": "Paid from the account balance. The proxy plan is active: …" } ]
}
Read messages[] on every document: payment_failed means the balance no longer covers the total and nothing was charged; purchase_failed is recoverable and says why; payment_instrument_unavailable means another handler was passed, and only balance exists for an agent.
Hand it to the person when the balance is short
A session in requires_escalation is not a failure: it is the point where the person takes over. Give them continue_url, which opens the dashboard with the plan preselected and the session id carried along; they pay by card, PayPal or crypto. Reading the session afterwards refreshes it: once that plan has been paid, the session becomes completed with the order.
# the message to the person, in your own words "The balance does not cover this plan. Pay it here, then tell me:" # then poll until completed (or canceled after 6 hours) curl -s https://api.quanticdata.io/v1/agent/ucp/checkout-sessions/chk_7d3f0a9b2c4e1f6a8b9c0d1e \ -H "Authorization: Bearer $QD_API_KEY" # declare the method to see the total a card would pay (22% VAT), without changing the plan curl -s -X PUT https://api.quanticdata.io/v1/agent/ucp/checkout-sessions/chk_7d3f0a9b2c4e1f6a8b9c0d1e \ -H "Authorization: Bearer $QD_API_KEY" -H "Content-Type: application/json" \ -d '{"payment_method":"PAYPAL_CARD"}'
The alternative is a top-up: the person adds balance on the dashboard (the smallest top-up is $5, and the balance never expires), and the agent completes the session itself at 0% VAT. Either way the agent never sees a card.
Generate proxy lines from the order
The order id is the orderId of the proxy endpoints. One call returns ready-to-use lines with the country, state, city or ISP targeting the plan supports, rotating or sticky sessions, and the format your HTTP client wants.
curl -s -X POST https://api.quanticdata.io/v1/public/proxies/generate \
-H "Authorization: Bearer $QD_API_KEY" -H "Content-Type: application/json" \
-d '{"orderId":"ord_8c21","country":"us","rotation":"sticky","sessionTime":10,"quantity":2,
"format":"http://user:pass@host:port"}'
{ "type": "response", "payload": { "proxies": [ "http://user_8c21-country-us-session-a1b2c3-sessTime-10:…@…:…",
"http://user_8c21-country-us-session-d4e5f6-sessTime-10:…@…:…" ] } }
# location values (states, cities, ISPs) come from the Proxy locations endpoints
curl -s "https://api.quanticdata.io/v1/public/geo/cities?country=us" -H "Authorization: Bearer $QD_API_KEY"
The generate-proxies skill teaches the username grammar; the buy and use proxies guide in the reference shows the same flow in Python with the non-UCP purchase call.
The rule for the agent
For CLAUDE.md, the project rules or the system prompt. It is what keeps a buying agent safe for the person who pays.
## Buying proxies on QuanticData
- Check GET /v1/public/balance before buying; pick the plan from GET /v1/public/plans, never from memory.
- Open ONE checkout session per plan with an Idempotency-Key; reuse the key on a retry.
- Complete only with the "balance" handler. If status is requires_escalation, give the user
continue_url, then poll GET /checkout-sessions/{id} until completed. Never ask for card details.
- A session already completed returns the same order: do not open a second one for the same need.
- Do not resend a purchase that timed out: read GET /v1/public/orders first.
- After completed: POST /v1/public/proxies/generate with order.id; keep the lines out of logs.
The setting to start with
A Residential plan from GET /v1/public/plans?planType=residentialpremium, one session with payment_method: BALANCE, complete with the balance handler, then generate with rotation: sticky. Top-ups and cards stay with the person; the agent spends only the balance.
Sources and standards
What this tutorial is built on, so you can check the shapes yourself:
Can the agent pay with a card?
No. The only payment instrument an agent holds is the prepaid balance of its own account, at 0% VAT. Card, PayPal and crypto payments are made by a person on the dashboard, through the continue_url the session carries. The agent never sees, asks for or stores card details.
What if the balance is short?
The session opens in requires_escalation with a continue_url. The agent gives the person that link, or asks for a top-up, and polls the session: once the plan is paid on the dashboard, or the balance covers it and the agent completes it, the session becomes completed with the order id. Nothing is charged twice.
Which plans can it buy?
Any public plan from GET /v1/public/plans: Residential Basic and Premium, mobile and datacenter, with their gigabytes, days and list price. ISP plans are configured per order (IPs, region, days) and go through the Premium ISP and IPv6 endpoints or the dashboard; trial-only and custom plans are not in the catalog.
Does a retry buy twice?
No. The Idempotency-Key on the create call returns the existing session, a completed session keeps answering with the same order, and the purchase itself is one call that either activates the plan or refunds the balance. If a complete call timed out, read the session or GET /v1/public/orders before anything else.
Is VAT charged?
Not from the balance or in crypto: those totals carry 0% VAT. When a person pays by card or PayPal on the dashboard the total includes 22% VAT, and the agent can see that figure in advance by declaring payment_method PAYPAL or PAYPAL_CARD on the session.
How does it get proxy lines after buying?
With POST /v1/public/proxies/generate and the order id: it returns lines in the format you ask for, with country, state, city or ISP targeting where the plan supports it, rotating or sticky sessions of up to 120 minutes. The location values come from the Proxy locations endpoints.
Let your agent buy what it needs
One session, one handler, one order id that turns into proxy lines. $2 of free API usage per month, no card.
Get my free API key