Build a reseller business on HProxy
The reseller loop over the HProxy API: fund a wallet, sell residential GB or dedicated IPs, deliver programmatically, get pushed on fulfillment and renew.
Everything a proxy storefront needs, over one API: prepaid wallet, server-authoritative quotes, idempotent orders, programmatic delivery for both residential lines and dedicated IPs, webhooks on fulfillment, and renewals. Your customers never see HProxy: every response is white-label by construction.
- 1Fund the wallet
POST /depositsreturns a hostedpayUrl(card or crypto). Everything below prepays from this balance and fails with an honest402when it's short. No surprise card charges, ever. - 2Quote before you sell
GET /products/{id}/pricereturns the exact amount the order will charge. For dedicated IPs passcountryandperiod_daystoo. Put your margin on top and show YOUR price. - 3Buy on demand
POST /orderswith anIdempotency-Key. Wallet-paid orders return in seconds; a retry with the same key can never double-charge. For residential the body isproduct_idplusquantityin GB and nothing else: the country is chosen in the next step. - 4DeliverResidential:
POST /plans/{id}/generateper customer request. Dedicated:GET /proxies?order_id=…once the order completes. - 5Attribute
PATCH /plans/{id}with alabel. Your reference rides on every read and every webhook for that plan after that. - 6Get pushed, don't poll
- 7Renew
POST /orderswithfulfillment_meta: {"kind": "extension", "ids": […]}renews exactly the proxies your customer keeps.
Selling residential GB: how plans work
One account holds one active plan per residential product, and every purchase tops it up. Buy 5 GB of residential-lite, then 3 GB more, and you have one plan with 8 GB, one credential pair and one balance. Generation is free and repeatable: every line you generate is that same credential with the country and session written into the username, and the plan's GB is drawn down only by the traffic that actually flows. There is no per-line metering, so lines you hand to different people share one balance.
That is the right shape for your own usage, trials and burst capacity, and the wrong shape for selling to more than one customer: whoever generates lines first can spend the other's traffic, and nothing in this lane can stop them. Isolation per customer is the Reseller API, described below: one header names your customer, and the call runs as an account of their own, with its own plan, its own credentials, its own GB cap and its own balance. That is the sub-user model, and it is the lane a storefront should be on before its second customer.
# The single-account loop: your own usage, or one trial pool.
# 1. Buy 10 GB. A later purchase of the same product tops up this plan.
curl -X POST https://hproxy.com/api/v1/orders \
-H "X-API-Key: hpx_your_key_here" -H "Idempotency-Key: pool-resi-10gb" \
-H "Content-Type: application/json" \
-d '{"product_id": "residential-lite", "quantity": 10}'
# 2. Your plan (one per residential product), with its remaining GB
curl https://hproxy.com/api/v1/plans -H "X-API-Key: hpx_your_key_here"
# 3. Tag it with your own reference
curl -X PATCH https://hproxy.com/api/v1/plans/{planId} \
-H "X-API-Key: hpx_your_key_here" -H "Content-Type: application/json" \
-d '{"label": "trial-pool"}'
# 4. Generate lines (free, repeatable; GB is spent by traffic only)
curl -X POST https://hproxy.com/api/v1/plans/{planId}/generate \
-H "X-API-Key: hpx_your_key_here" -H "Content-Type: application/json" \
-d '{"count": 100, "country": "US", "stickyMinutes": 10}'
# 5. Read the balance any time (synced about every 30 minutes)
curl https://hproxy.com/api/v1/plans/{planId} -H "X-API-Key: hpx_your_key_here"GET /plans after each order instead of expecting a new one, and use the Reseller API below for isolation per customer.Sub-users: one account per customer, over one header
On the Reseller API your key names a customer with X-Reseller-Customer-Id, and every call runs as that customer: POST /orders provisions their own plan and credentials, GET /plans lists only theirs, GET /wallet is the credit you issued them, and GET /customers is your whole book. Customer A can never generate from customer B's plan, because they are different accounts. Nothing else about the API changes. The lane is granted rather than self-served, and getting on it is four steps:
- 1Apply from your dashboardSign in and open Reseller: your business name, a few lines about what you sell, and the Partner Agreement. The application is tied to the account whose key you already use, so there is nothing to re-create.
- 2We review it, in personEvery partner is onboarded by a person, the founder included. We reply on the email of your account and ask for a Telegram or WhatsApp contact, so you have a direct line for the whole time you sell on the platform.
- 3Approval provisions the laneYour account gets a rate card and a business dashboard (balance, customers, your prices, statement, support inbox). In the dashboard, under Storefront, API access, you create your reseller API key yourself: it carries the
act_as_reseller_customerscope, it is shown once, and it is the key that names customers. The key you have today keeps working for your own account. - 4Put customers behind the headerAdd
X-Reseller-Customer-Id: <your id for them>to any call. The first call creates the customer;PUT /customer/contactattaches their email and a display name; an order as them provisions their own plan. The full loop is on the Reseller API page.
Selling dedicated IPs (IPv4 / IPv6 / ISP / Mobile)
# 0. Show your customer the countries in stock right now (name + alpha3),
# plus the rental periods. Always current: sold-out countries drop out.
curl https://hproxy.com/api/v1/products/ipv4/options -H "X-API-Key: hpx_your_key_here"
# 1. Quote the exact charge for the targeting your customer picked
curl "https://hproxy.com/api/v1/products/ipv4/price?quantity=5&country=DEU&period_days=30" \
-H "X-API-Key: hpx_your_key_here"
# 2. Buy with the same targeting
curl -X POST https://hproxy.com/api/v1/orders \
-H "X-API-Key: hpx_your_key_here" -H "Idempotency-Key: cust-1042-ipv4-de-5" \
-H "Content-Type: application/json" \
-d '{"product_id": "ipv4", "quantity": 5,
"fulfillment_meta": {"country": "DEU", "period_days": 30}}'
# 3. On the order.fulfilled webhook (or once GET /orders/{id} says completed):
curl "https://hproxy.com/api/v1/proxies?order_id={orderId}" -H "X-API-Key: hpx_your_key_here"
# -> ip, ports, username, password per proxy. Hand them to your customer.
# 4. Renewal, 30 more days for the proxies the customer kept
curl -X POST https://hproxy.com/api/v1/orders \
-H "X-API-Key: hpx_your_key_here" -H "Idempotency-Key: cust-1042-renew-jul" \
-H "Content-Type: application/json" \
-d '{"product_id": "ipv4", "quantity": 2,
"fulfillment_meta": {"kind": "extension", "ids": ["9214321", "9214322"], "period_days": 30}}'Renewals are ownership-checked server-side: the ids (from GET /proxies) must belong to the calling account, and the renewal is priced for exactly those proxies. quantity should match the number of ids.
Selling scrapers
A scraper call is charged to your own balance at our normal per-call price, the same as for every customer, whether you call it for yourself or for a customer of yours. Put your own price on top in your billing. The Scraper API pages list every endpoint and its price.
data defensively, subscribe to service notices, and do not promise your customers that a scraper will never change or never fail. The envelope around data keeps its shape.What stays stable when we change things underneath
The networks behind a product change, sometimes at short notice, and a storefront should never notice. Build on the things we keep stable and treat everything else as a value to read, not to remember:
- 1Product ids
residential-lite,residential-premium,ipv4and the rest are ours and stay put when the pool behind them is swapped. ReadGET /productsforavailableand the targeting contract instead of hardcoding either. - 2Plan ids and balancesA plan id never changes meaning: the plan keeps serving its remaining gigabytes from the pool it was bought on. When we move a product to a new pool, the next purchase of that product opens a fresh plan beside the old one, so for a while
GET /planscan list two plans for one product. List plans and read their balances rather than assuming one per product, and read plan ids from the API after an order completes rather than predicting them. - 3Lines, generated on demandGenerate through
POST /plans/{id}/generatewhen a customer needs lines, and hand those out. The credentials inside a line can rotate when a pool moves, so do not store lines for longer than a session or bake them into a customer's config. - 4Order and proxy idsRenewals and lookups run on our ids (
orderId, theidinGET /proxies), never on anything that names a network. - 5NoticesA change that needs something from you arrives as an
ACTION_REQUIREDservice notice: in the feed, as theannouncement.publishedwebhook, and by email to the account. Subscribe once and you will not learn about a change from a failing request.
Our side of it: fields and codes are only ever added, never renamed or removed, and an existing code keeps its meaning. If a call ever has to change how it behaves, the change is announced as an ACTION_REQUIRED notice with a date before it happens, and the old behaviour keeps working until that date. Nothing in a response names a network or a provider, so a pool change is not something your code can see.
Safety rails for production
Send an Idempotency-Key on every write, so retries converge instead of double-charging. Put a daily spend cap on the key in your dashboard, so a leak can't drain the wallet. Verify webhook signatures before trusting a delivery. Branch on the machine code in error bodies (402 = top up, 429 = back off per Retry-After). And generate your client from the OpenAPI spec instead of hand-writing one.
Need a hand wiring this up? Email support@hproxy.com. A real person reads every message.