Introduction
The VaultProxies Reseller API gives you programmatic control over the same proxy infrastructure the dashboard runs on, and every order placed through it is billed at your wholesale rate. It covers the whole life of a plan:
- Pricing and catalogue. The public price book (pricing), every plan your key can order at your rate (categories), dedicated ISP pools with live stock (ISP pools) and Residential Unlimited speeds with live availability (unlimited speeds).
- Ordering. New plans and top-ups (create order) and renewals by service id (extend).
- Plan management. Every plan with its credentials and what is left (list services), daily usage history (usage), and password rotation, suspend and resume, labels, deletion and IP allow-lists.
- Proxy generation. The countries (countries) and full geo options (locations) each plan can target, then ready-to-use lines (generate), with the hosts and ports they connect to.
Every call takes one header and speaks JSON over HTTPS. No SDK, no client to install: drop a curl command into your stack and you are running. Python and Node examples are inline on the main endpoints below.
Authentication
Every request must include your API key in the X-API-Key header. For POST requests also send Content-Type: application/json. Keys are issued from the reseller dashboard after your account is approved, and only work for approved reseller accounts: a key whose account is not an approved reseller is refused with 403. The one endpoint that needs no key is the public price book, GET /api/reseller/pricing.
curl -H "X-API-Key: YOUR_API_KEY" \
https://vaultproxies.net/api/reseller/balanceBase URL
All endpoints below are relative to:
https://vaultproxies.netReseller pricing
Every order placed with a reseller API key is billed at the reseller rate, not the public retail rate, so there is nothing to enable. Coupons do not combine with it: an API order carrying one is refused with 400. The table below is live, read from GET /api/reseller/pricing, so it always matches what you are charged.
These are the standard wholesale rates. Signed in to a reseller account, the table shows your own, after any reseller loyalty discount. From code, GET /api/reseller/categories with your key returns your rate as price_per_unit_cents.
| Proxy type | Key | Your cost | Public retail | Margin |
|---|---|---|---|---|
Time-priced plans (e.g. dc_unlim) show the per-day rate; pass week or month as time_unit when ordering for those tiers. Residential Unlimited is priced per speed and pool: order it with speed and pool.
The price book endpoint
/api/reseller/pricingPublic: no API key needed, so you can build a price page or work out your margin before you hold a key. Every plan on sale, with wholesale_per_unit_cents (your cost), retail_per_unit_cents (our public price), margin_percent (the spread between the two) and unit (what one unit buys: GB, HOUR, DAY and so on). Residential Unlimited also carries speed_tiers, the same figures per speed and pool, and retail_duration_discounts, the bulk ladder retail orders get by length. Wholesale is flat at any length, so that ladder never applies to your orders. Sent with a signed-in reseller's session token, the wholesale figures already include that reseller's loyalty discount, reported as loyalty_discount_pct; anonymous callers get 0.
curl "https://vaultproxies.net/api/reseller/pricing"Response
{
"pricing": [
{
"key": "resi_pergb",
"display_name": "Residential /GB",
"unit": "GB",
"pricing_type": "pergb",
"wholesale_per_unit_cents": 50,
"retail_per_unit_cents": 100,
"margin_percent": 50
},
{
"key": "resi_unlim",
"display_name": "Residential Unlimited",
"unit": "HOUR",
"pricing_type": "unlim",
"wholesale_per_unit_cents": 200,
"retail_per_unit_cents": 400,
"margin_percent": 50,
"speed_tiers": [
{
"speed_mbps": 1000,
"label": "1 Gbps",
"pool": "main",
"pool_label": "Main pool",
"wholesale_per_hour_cents": 250,
"retail_per_hour_cents": 500,
"margin_percent": 50
}
],
"retail_duration_discounts": [ /* { "min_hours", "percent_off" }, shortest first */ ]
}
],
"loyalty_discount_pct": 0
}Prices in the examples on this page are illustrative; read them from the response. Want the full retail price book in one page? See /pricing.
Get balance
Returns your current account balance in cents. Divide by 100 for the dollar amount. The same value is shown on the reseller dashboard wallet card.
/api/reseller/balancecurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/balance"Response
{
"balance_cents": 15000
}List categories
Returns every plan you can order, priced for your key. price_per_unit_cents is the reseller rate you are billed at, not retail; retail_price_per_unit_cents is our public price for the same unit, so the difference is your margin. volume_tiers is null whenever your rate is flat. Pass a key as category_key when ordering. Cache the response on your side, the catalog moves slowly.
hidden: true marks a plan that is not on the price list because it is sold as part of another: eu_isp is the Europe region of shared_isp, and stays orderable while shared_isp is on sale. resi_unlim also carries speed_tiers (your hourly rate per speed and pool) and duration_discounts, the retail ladder, published for reference.
/api/reseller/categoriescurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/categories"Response
{
"categories": [
{
"id": 1,
"key": "resi_pergb",
"display_name": "Residential /GB",
"pricing_type": "pergb",
"unit": "GB",
"price_per_unit_cents": 50,
"retail_price_per_unit_cents": 100,
"min_units": 1,
"max_units": 5000,
"unit_block_hours": 0,
"hidden": false,
"volume_tiers": null
},
{
"id": 3,
"key": "dc_unlim",
"display_name": "Datacenter Unlimited",
"pricing_type": "unlim",
"unit": "DAY",
"price_per_unit_cents": 250,
"retail_price_per_unit_cents": 500,
"min_units": 1,
"max_units": 61,
"unit_block_hours": 24,
"hidden": false,
"volume_tiers": null
}
]
}Create order
Provisions a new plan against your balance. Name the plan with category_key, the quantity with units, and for time-based plans the billing window with time_unit. A successful order answers 201 with the new credentials and the paid invoice. To add GB or time to a plan you already hold, send the same body with update_service_id (below), or call services/extend, which works the plan out for you.
/api/reseller/ordercurl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category_key": "resi_pergb", "units": 5}' \
"https://vaultproxies.net/api/reseller/order"Request body
// 5 GB of residential
{ "category_key": "resi_pergb", "units": 5 }
// one week of datacenter unlimited
{ "category_key": "dc_unlim", "units": 1, "time_unit": "week" }category_key takes any key on the price book: every key GET /api/reseller/categories returns without hidden: true. eu_isp, the Europe region of shared_isp, is orderable too. Every field is listed under order parameters.
Response
{
"service": {
"id": 123,
"user_id": 1,
"category_id": 1,
"status": "active",
"pricing_type": "pergb",
"unit": "GB",
"remaining_gb": 5,
"purchased_units": 5,
"username": "abc123xyz",
"password": "secretpass123",
"created_at": "2026-05-05T12:00:00Z",
"updated": false
},
"invoice": {
"id": 456,
"amount_cents": 250,
"status": "paid"
}
}Top up an existing plan
Pass update_service_id with the id of a plan you own; category_key must be that plan's. units is added: GB on a per-GB plan, time on a time-based one. The credentials do not change. An expired plan can be topped up back to life, unless its capacity was already released, in which case it needs a new order.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category_key": "resi_pergb", "units": 5, "update_service_id": 123}' \
"https://vaultproxies.net/api/reseller/order"{
"service": {
"id": 123,
"status": "active",
"remaining_gb": 9.5,
"username": "abc123xyz",
"password": "secretpass123",
"updated": true
},
"invoice": { "id": 457, "amount_cents": 250, "status": "paid" }
}Dedicated ISP orders
dedicated_isp takes two extra fields. pool is required: stock is finite per pool and is checked before you are charged, so an order without it is rejected with a 400. Pool IDs are upper-case, shaped ISP_<REGION>_<USE> (e.g. ISP_US_SNEAKERS, ISP_UK_RETAILPLUS). Fetch the pools and their live stock from GET /api/reseller/proxy/isp-pools first. term_days is a multiple of 30, from 30 to 360 days (default 30), fixed at purchase.
{
"category_key": "dedicated_isp",
"units": 1,
"pool": "ISP_US_SNEAKERS", // required, see GET /api/reseller/proxy/isp-pools
"term_days": 30 // optional: a multiple of 30, up to 360 (default 30)
}units is the number of exclusive IPs, and each is delivered with its own credential rather than one pair for the plan. To renew, extend the plan with the term_days to add: every IP on it is renewed and keeps its address, and units is ignored. A plan that has already ended has released its IPs and needs a new order.
Residential Unlimited orders
resi_unlim is sold by line speed, by the hour. speed is 200, 400 or 1000 (Mbps; "1gbps" works too) and pool is main or legacy:
- Main pool: every speed, with country, city and ASN targeting and sticky sessions up to 3 hours. Lines connect to
gate-eu.vaultproxies.comon 8080 (HTTP) and 1080 (SOCKS5). - Legacy pool: 400 Mbps only, with country targeting and sticky sessions up to 24 hours. Lines connect to
resi.vaultproxies.comon 8080 (HTTP) and 1080 (SOCKS5).
An order naming neither field is the Legacy pool at 400 Mbps, exactly as before speeds existed, and a speed without a pool goes to the Main pool. One order or extension buys at most 4,320 hours (180 days).
{
"category_key": "resi_unlim",
"units": 24,
"time_unit": "hour",
"speed": 1000, // 200, 400 or 1000
"pool": "main" // "main" (every speed) or "legacy" (400 only)
}Main-pool lines are limited by what is free right now. An order that cannot be served for that long is refused with a 409 naming the longest duration that can be bought, before anything is charged. Read your rates and live availability per speed first from GET /api/reseller/unlimited/speeds. Extending keeps the line's speed and pool; send neither when extending. Wholesale is flat at any length: the bulk discount retail orders get by length is not applied on top of it.
ISP pools
Pools available for dedicated_isp, with live stock. pool is required when ordering dedicated_isp, so fetch this first. Only pools that can be fulfilled right now are returned, so any pool value from here is safe to order against, as long as stock covers your units.
/api/reseller/proxy/isp-poolscurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/proxy/isp-pools"{
"pools": [
{
"pool": "ISP_US_SNEAKERS",
"title": "US Sneaker Proxies (ISP)",
"stock": 6279,
"in_stock": true,
"is_subnet": false
}
]
}Unlimited speeds
Every Residential Unlimited speed with your wholesale hourly rate and, per pool, whether it can be sold right now. status is available, limited (bookable, but for less than 30 days), sold_out or paused; max_hours is the longest line that can be bought right now. max_order_hours is the ceiling on one order. duration_discounts is the retail bulk ladder, published for reference: duration_discount is false on wholesale lines, so it never applies to your orders.
/api/reseller/unlimited/speedscurl -H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/unlimited/speeds"{
"speeds": [
{
"speed_mbps": 1000,
"label": "1 Gbps",
"pools": [
{
"pool": "main",
"label": "Main pool",
"available": true,
"max_hours": 720,
"status": "available",
"price_per_hour_cents": 250,
"retail_per_hour_cents": 500,
"duration_discount": false
}
]
}
],
"max_order_hours": 4320,
"from_price_per_hour_cents": 150,
"duration_discounts": [ /* { "min_hours", "percent_off" }, shortest first */ ],
"default": { "speed_mbps": 400, "pool": "legacy" }
}One line, before you extend it
/api/reseller/services/unlimited?service_id=124One Residential Unlimited line: its speed, pool, your hourly rate and max_extend_hours, how far it can be extended right now. A Main-pool line can only be extended as far as the capacity behind it allows, so ask this before offering an extension. An id your account does not own answers 404.
{
"service_id": 124,
"speed_mbps": 1000,
"speed_label": "1 Gbps",
"pool": "main",
"pool_label": "Main pool",
"end_at": "2026-09-16T08:00:00Z",
"price_per_hour_cents": 250,
"max_extend_hours": 336,
"duration_discount": false,
"duration_discounts": [ /* { "min_hours", "percent_off" }, shortest first */ ]
}Extend a plan
Adds GB to a per-GB plan or time to a time-based one. It is the same operation as update_service_id on /order, under the name most integrators reach for first: the plan is worked out from service_id, so you do not repeat category_key. Send time_unit for time-based plans. On a dedicated ISP plan send term_days instead: units is ignored and every IP on the plan is renewed. A Residential Unlimited line keeps its speed and pool. An id your account does not own answers 404; success is 201, like an order.
/api/reseller/services/extendcurl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123, "units": 5}' \
"https://vaultproxies.net/api/reseller/services/extend"{
"service": { "id": 123, "status": "active", "remaining_gb": 9.5, "updated": true },
"invoice": { "id": 457, "amount_cents": 250, "status": "paid" }
}List services
Every plan on your account with its credentials, what each has used and what is left. Use it to hand fresh credentials to your customers, or to poll for top-up triggers. Data plans report purchased_gb, used_gb and remaining_gb. Time-based plans report started_at, expires_at, and the total, elapsed and remaining time in seconds. Residential Unlimited lines add speed_mbps and pool. label is the name you gave the plan, when set.
/api/reseller/servicescurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/services"Response
{
"services": [
{
"id": 123,
"username": "abc123xyz",
"password": "secretpass123",
"status": "active",
"plan": "resi_pergb",
"plan_name": "Residential /GB",
"pricing_type": "pergb",
"unit": "GB",
"purchased_units": 10,
"purchased_gb": 10,
"used_gb": 5.5,
"remaining_gb": 4.5,
"label": "customer-42",
"created_at": "2026-09-01T12:00:00Z"
},
{
"id": 124,
"username": "def456uvw",
"password": "secretpass456",
"status": "active",
"plan": "resi_unlim",
"plan_name": "Residential Unlimited",
"speed_mbps": 1000,
"pool": "main",
"pricing_type": "unlim",
"unit": "HOUR",
"purchased_units": 24,
"created_at": "2026-09-15T08:00:00Z",
"started_at": "2026-09-15T08:00:00Z",
"expires_at": "2026-09-16T08:00:00Z",
"duration_seconds": 86400,
"elapsed_seconds": 30600,
"remaining_seconds": 55800
}
]
}Usage history
Data used per day, in GB, for one plan (service_id) or for all your plans together, so you can bill your own customers. Choose the range with days (1 to 366, default 30, ending today) or with from and to (YYYY-MM-DD, both included, up to 366 days). Days are UTC, and a day without traffic comes back as 0, not a gap. history_starts is the first day usage was recorded on your account: earlier days show 0 because nothing was recorded then, not because nothing was used. Without service_id, by_service lists each plan's total for the range, highest first.
/api/reseller/services/usagecurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/services/usage?service_id=123&days=30"
# or a fixed range, for the whole account
curl -H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/services/usage?from=2026-09-01&to=2026-09-15"{
"from": "2026-09-14",
"to": "2026-09-16",
"days": 3,
"total_gb": 2.75,
"history_starts": "2026-08-27",
"points": [
{ "date": "2026-09-14", "gb": 1.25 },
{ "date": "2026-09-15", "gb": 0 },
{ "date": "2026-09-16", "gb": 1.5 }
],
"by_service": [
{ "service_id": 123, "gb": 2.5 },
{ "service_id": 125, "gb": 0.25 }
]
}Manage plans
Rotate a leaked password, cut off an end customer, name a plan, end it, or lock it to specific IPs. All of these are POST with a JSON body carrying service_id, and each answers 404 for an id your account does not own. Each change has its own endpoint because each carries a different consequence.
Rotate the password
/api/reseller/services/passwordRotates the proxy password on a plan you own, active or suspended. Omit password to have a strong one minted for you, or send your own. This is a rotation, not a reset: when changed is true, every credential currently in use stops working, which is the point when one has leaked. Allow up to 60 seconds for the change to reach every gateway. Send the password the plan already has and nothing happens: 200 with changed: false and a note saying so, no credential disturbed.
What a password of your own may contain depends on the plan:
- Letters and digits are always safe.
:@/and whitespace are never allowed, because credentials are handed out asuser:pass@host:portlines. - On plans whose credential we store, any other printable ASCII character is accepted and the length is 8 to 64 characters.
- On plans whose login lives on the network itself, letters and digits only, 6 to 32 characters. So
Str0ng!Passis fine on the first kind and a400on the second. - Leading and trailing spaces are trimmed before the check, so a value made only of spaces counts as omitted and a password is minted instead.
- Every rejection quotes the rule that applies to that plan, charset and range together, so read the message rather than inferring the kind.
Some plans issue their own pair rather than accepting one: dc_unlim always, and any plan whose login was never branded for our gateway. On those, password must be omitted (sending one is refused with 400 and the reason), and the response carries a new username as well as a new password, so every proxy line you have handed out has to be updated, not just the password half.
Which kind a plan is belongs to that individual plan rather than to its type, so two plans with the same plan key can differ: do not branch on plan. Send the request, read username back from the response (a changed username means the pair was regenerated) and treat the 400 as the signal to retry without password. Three kinds of plan cannot be rotated at all and answer 400 with the reason: one whose login is managed outside VaultProxies, one still finishing setup, and one issued before self-service logins existed, which support has to reissue.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123}' \
"https://vaultproxies.net/api/reseller/services/password"// request: { "service_id": 123, "password": "YourOwnPass123" } (password optional)
{
"service_id": 123,
"username": "abc123xyz",
"password": "K7mQp2xRt9wLzB4n",
"changed": true,
"note": "Existing credentials stop working. Allow up to 60 seconds for the change to reach every gateway."
}Suspend and resume
/api/reseller/services/suspendStops a plan authenticating without destroying it. Use this to cut off an end customer: nothing is deleted and no bandwidth is lost, so it can be resumed at any time. No refund or credit is issued, and a time-based plan keeps expiring while suspended: suspension cuts off access, it does not pause billing. Connections stop being accepted within about a minute. Safe to call twice (the second answers changed: false).
/api/reseller/services/resumeRe-enables a suspended plan. Connections are accepted again within about a minute. Only a suspended plan can be resumed; an expired or cancelled one cannot.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123}' \
"https://vaultproxies.net/api/reseller/services/suspend"// suspend
{ "service_id": 123, "status": "suspended", "changed": true, "note": "…" }
// resume
{ "service_id": 123, "status": "active", "changed": true, "note": "…" }Label a plan
/api/reseller/services/updateSets your own label on a plan, so you can tell which of your customers it belongs to without keeping a separate spreadsheet. Up to 120 characters, no line breaks; send an empty string to clear it. Purely descriptive: nothing about the proxy changes, and the label stays on your account. It never appears in a connection. The label comes back on list services.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123, "label": "acme-corp / seat 4"}' \
"https://vaultproxies.net/api/reseller/services/update"{ "service_id": 123, "label": "acme-corp / seat 4" }Delete a plan
/api/reseller/services/deletePermanently ends a plan and releases its capacity. This cannot be undone: remaining bandwidth and unused days are forfeited, and no refund or credit is issued. It requires confirm: true. Without it the call is refused with 400 and tells you what would be lost (forfeits). If you only want to cut off an end customer, suspend instead: it is reversible and keeps the bandwidth.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123, "confirm": true}' \
"https://vaultproxies.net/api/reseller/services/delete"// with confirm: true
{ "service_id": 123, "deleted": true, "note": "…" }
// without it (400)
{
"error": "confirmation required",
"message": "…",
"service_id": 123,
"forfeits": { "remaining_gb": 4.5 }
}IP allow-list
/api/reseller/services/allowed-ipsLocks a plan to specific source IPs. Dedicated ISP plans only: every other plan is refused with 400, so check the plan type before you build this into a flow. The list replaces any previous one, so you always know the resulting state without reading it back. Send an empty array to clear it and go back to username and password only.
- The list is checked before the plan is, so shape errors come back first whatever you sent them for: more than 10 addresses, a CIDR range, or an entry that is not a single address is its own
400on every plan, so list each address individually. - Entries are not verified to be real IP addresses, so a malformed one gets past this check and fails later, when the list is applied.
- Only once the list is accepted does the plan decide. On a plan served through the VaultProxies gateway the call is refused with an explanation: the gateway connects out to the network, your machine does not, so an allow-list there would authorise nobody and lock you out.
- On every other plan it is refused as not available. Where the plan supports it, the refusal adds that the username and password are the access control (rotate them with services/password); a plan managed outside VaultProxies, one issued before self-service logins existed, or one still finishing setup gets the bare refusal, because it has no credential to rotate either.
- A
502carrying a reference means the list could not be applied right now and nothing was changed: retry shortly.
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123, "ips": ["203.0.113.10", "203.0.113.11"]}' \
"https://vaultproxies.net/api/reseller/services/allowed-ips"{
"service_id": 123,
"allowed_ips": ["203.0.113.10", "203.0.113.11"],
"note": "This list replaces any previous one. An empty list restores username/password-only access."
}Countries
The country list for a plan, for a country picker. Pass the plan with plan_key (defaults to resi_unlim) and optionally country to narrow it. It reads the same data as generator locations, which is the full reference when you also need sub-country targeting. ipv6_pergb and resi_unlim_budget return an empty list here; read the budget plan's countries from the locations endpoint.
/api/reseller/countriescurl -H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/countries?plan_key=resi_pergb"{
"countries": [
{ "code": "US", "name": "United States" },
{ "code": "GB", "name": "United Kingdom" }
]
}Generator locations
Lists what you can geo-target for a plan. Pass the plan with plan_key (defaults to resi_unlim); add country to narrow to one country. What comes back depends on the plan:
resi_pergb: the countries its network serves, each with the cities it can actually reach. A city outside that list is refused rather than ignored, so read this endpoint rather than hard-coding names.resi_lite_pergb: every country, and withcountry=USthe US states. Cities are not listed: this pool takes a city by GeoNames id (extra.geoname_id), not by name.pool4_pergb: countries, US states and their cities.resi_unlimwithpool=main: the Main pool's countries, each with the cities it can reach, the same rules asresi_pergb.resi_unlim(Legacy pool, withoutpool),mobile_pergb,shared_isp,eu_isp,dc_pergbandresi_unlim_budget: countries only. These pools accept a state or a city segment and then ignore it, so both fields are dropped rather than sent.ipv6_pergb: an empty list, it has no geo targeting.
/api/reseller/proxy/generator/locationscurl -X GET \
-H "X-API-Key: YOUR_API_KEY" \
"https://vaultproxies.net/api/reseller/proxy/generator/locations?plan_key=resi_pergb&country=US"Response
{
"countries": [
{
"code": "US",
"name": "United States",
"states": [
{ "code": "CA", "name": "California" },
{ "code": "NY", "name": "New York" }
]
}
]
}Generate proxies
Turns one of your active services into ready-to-use proxy lines. Supports rotating and sticky sessions, geo targeting (where the plan allows it), HTTP and SOCKS5, and several output formats. The response always carries the exact hostname and port to connect to, so you never have to hardcode gateways.
/api/reseller/proxy/generations/createcurl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"service_id": 123,
"plan_key": "resi_pergb",
"country": "US",
"protocol": "HTTP",
"format": "user:pass@ip:port",
"extra": { "mode": "sticky", "count": 5, "session_seconds": 600 }
}' \
"https://vaultproxies.net/api/reseller/proxy/generations/create"Response
{
"generations": [
{
"id": 1751712000000000000,
"user_id": 1,
"service_id": 123,
"plan_key": "resi_pergb",
"country": "us",
"protocol": "HTTP",
"format": "user:pass@ip:port",
"hostname": "gate-eu.vaultproxies.com",
"port": 80,
"username": "abc123xyz-geo-us-sess-k2j9x1pq-life-600",
"password": "secretpass123",
"output_line": "abc123xyz-geo-us-sess-k2j9x1pq-life-600:[email protected]:80",
"created_at": "2026-07-05T12:00:00Z"
}
],
"generation": { "...": "first entry of generations, same shape" }
}Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id | integer | Yes | Active service to generate from. Must belong to your account and be status active. |
plan_key | string | Yes | Must match the service's plan, e.g. resi_pergb, resi_lite_pergb, resi_unlim, resi_unlim_budget, dc_unlim, dc_pergb, mobile_pergb, pool4_pergb, ipv6_pergb, ipv6_dc_pergb, ipv6_dc_unlim, shared_isp (US ISP), eu_isp (EU ISP). |
protocol | string | No | HTTP (default) or SOCKS5. Picks the port in the generated line, see the per-plan table below. |
format | string | No | Output line format: ip:port:user:pass (default), user:pass@ip:port, ip:port@user:pass, user:pass:ip:port, ip:port:pass:user, protocol://user:pass@ip:port, protocol://ip:port, ip:port, user:pass. host: is accepted in place of ip:. |
country | string | No | ISO-2 code (e.g. US) or full name, see the locations endpoint for what each plan allows. On dc_unlim it only picks the EU vs US gateway; ignored on ipv6_pergb. On resi_unlim_budget country is the only geo dimension, state and city are ignored. |
region | string | No | resi_pergb and resi_lite_pergb: a multi-country grouping. Continent codes (EU, NA, SA, AS, AF, OC) or a finer region (nordics, dach, benelux, euwest, eueast, apac, mena, latam). Mutually exclusive with country, state and city (they are cleared when set). The old name continent is still accepted. |
state | string | No | State code or name. Respected on resi_lite_pergb (the locations endpoint lists the US states; elsewhere use the ISO 3166-2 code) and pool4_pergb (US, two-letter code). Plans with no state dimension (resi_pergb, resi_unlim, resi_unlim_budget, mobile_pergb, shared_isp, eu_isp, dc_pergb) drop this field. |
city | string | No | City name. Respected on resi_pergb and pool4_pergb. On resi_pergb it must be a city the locations endpoint lists for that country: an uncatalogued name is refused, not ignored. NOT on resi_lite_pergb: that pool rejects a city name, so use extra.geoname_id there (e.g. 5368361 for Los Angeles). On resi_unlim it is respected on Main-pool lines (a catalogued city, as on resi_pergb) and dropped on Legacy-pool lines, which are country-only. |
gate | string | No | auto (default) or a gate id from the gates array of GET /api/plans/catalog, which is the live list; an id not in it is refused. Moves the lines to that gate: ports, credentials and the exit IP stay the same. auto is the plan's recommended gate and is fastest for almost everyone. Refused on plans without a gate choice (gate_selectable in the catalogue). |
ips | string[] | No | shared_isp only: static IPs (e.g. ["83.245.53.70"]) to pin each line to. One line is emitted per IP and extra.count is ignored. Mutually exclusive with sticky mode. |
extra.postal_code | string | No | resi_lite_pergb only: exact postal code, letters and digits, up to 12 characters (e.g. 90011, SW1A1AA). Works best combined with country. With no node online in that code the connection is refused rather than moved to a nearby one. |
extra.dma | integer | No | resi_lite_pergb only: US Nielsen metro (DMA) code, 501 New York, 803 Los Angeles. |
extra.geoname_id | integer | No | resi_lite_pergb only: exact city by GeoNames ID (e.g. 5128581 for New York City). Unambiguous where city names collide, prefer it over city when you know the ID. |
extra.asn | integer | No | Autonomous system number, digits only, no AS prefix (e.g. 13335). Honoured where the plan targets ASN: resi_pergb, resi_lite_pergb, mobile_pergb, pool4_pergb and Main-pool resi_unlim (see the capability table). |
extra.isp | string | No | resi_lite_pergb only: ISP or carrier name. It is reduced to the slug the pool stores: punctuation and spacing are removed and corporate words are dropped, so T-Mobile is sent as tmobile and Charter Communications as charter. |
extra.timezone | string | No | resi_lite_pergb only: IANA timezone (e.g. America/New_York). Case-sensitive, 32 characters at most. |
extra.latitude | number | No | resi_lite_pergb only: radius-search centre latitude, -90 to 90. Requires longitude; ignored on its own. |
extra.longitude | number | No | resi_lite_pergb only: radius-search centre longitude, -180 to 180. Requires latitude; ignored on its own. |
extra.radius_km | integer | No | resi_lite_pergb only: radius in km around latitude/longitude. 1-100; larger values are clamped to 100. Any node inside the circle may be used. The compass letters are added for you, so pass plain signed decimals. |
extra.mode | string | No | rotating (default) or sticky. Sticky keeps the same IP for the session window. Not available on ipv6_pergb or eu_isp (always rotating). |
extra.count | integer | No | How many proxy lines to generate. 1-10000, default 1. |
extra.session_seconds | integer | No | Sticky session lifetime in seconds (default 600). Caps: resi_pergb and Main-pool resi_unlim 10,800 (3 h); resi_lite_pergb 21,600 (6 h); shared_isp, resi_unlim_budget, dc_pergb, dc_unlim, ipv6_dc_pergb and ipv6_dc_unlim 86,400 (24 h). Legacy-pool resi_unlim (up to 86,400, 24 h) and mobile_pergb (up to 7,200, 2 h) are converted to whole minutes, so pass at least 60. pool4_pergb holds a session for about 10 minutes whatever you send. Ignored on eu_isp. |
extra.session_minutes | integer | No | Alternative to session_seconds, sticky lifetime in minutes. Ignored when session_seconds is also set. |
extra.session_length | string | No | eu_isp only: long (default) or short. Accepted for compatibility, but this pool rotates on every request whatever you send, so treat EU ISP as rotating-only and do not build a flow that depends on holding one exit. |
Proxy hosts & ports
The hostname and port your customers connect through. Each gateway serves several products, HTTP and SOCKS5 may use different ports, and Residential Unlimited's two pools connect to different hosts. The generate response always returns the exact hostname and port, so treat this as a reference rather than something to hardcode.
Hostnames are always ours. To give your customers your own domain, point a CNAME at our host (or an A record at its IP, which an apex domain needs) and substitute it in the lines you hand out, or run your own gateway in front and forward with the credential. Authentication is by username and password alone, so a name pointed at ours connects exactly the same, with no setup on our side.
| Proxy type | Type | Hostname | Port (HTTP / SOCKS5) |
|---|---|---|---|
| Gateway Europe | CNAME | resi_pergb: 80 resi_lite_pergb: 80 resi_unlim (Main pool): 8080 / 1080 mobile_pergb: 8080 / 1080 eu_isp: 30 / 31 | |
| resi_unlim (Legacy pool) | CNAME | 8080 / 1080 | |
| dc_unlim | CNAME | 10808 | |
| Gateway United States | CNAME | pool4_pergb: 10000 / 11000 dc_pergb: 777 / 666 shared_isp: 30 / 31 ipv6_pergb: 30 / 31 ipv6_dc_pergb: 30 / 31 ipv6_dc_unlim: 30 / 31 |
These are the hostnames your customers connect through. Click any value to copy.
Built from the public plan catalogue. Signed in to your account, this table also lists the A-record target for every host and the names under your branded domain.
Per-plan capabilities
Every plan's default host, ports, geo targeting and sticky-session limit, one row per pool where a plan has more than one. Read live from GET /api/plans/catalog, which is public and built by the same function the generator uses: read it from your code rather than hard-coding this table.
| Plan | Host | HTTP / SOCKS5 | Geo targeting | Sticky sessions |
|---|---|---|---|---|
resi_pergb | gate-eu.vaultproxies.com | 80 / 80 (shared) | Country, region, city, ASN, region is mutually exclusive with country and city | Up to 3 h (session_seconds ≤ 10800) |
resi_lite_pergb | gate-eu.vaultproxies.com | 80 / 80 (shared) | Country, continent, state, postal code, metro (DMA), GeoNames id, ASN, ISP, timezone, radius, continent is mutually exclusive with country and state | Up to 6 h (session_seconds ≤ 21600) |
resi_unlim (Main pool) | gate-eu.vaultproxies.com | 8080 / 1080 | Country, city, ASN | Up to 3 h (session_seconds ≤ 10800) |
resi_unlim (Legacy pool) | resi.vaultproxies.com | 8080 / 1080 | Country | Up to 24 h (session_seconds ≤ 86400), converted to whole minutes, pass at least 60 |
resi_unlim_budget | assigned per service | returned by generate | None | Up to 24 h (session_seconds ≤ 86400) |
dc_unlim | eu-dc.vaultproxies.com | 10808 / 10808 (shared) | Country, picks the EU or US gateway only | Up to 24 h (session_seconds ≤ 86400) |
pool4_pergb | gate-us.vaultproxies.com | 10000 / 11000 | Country, state, city, ASN | About 10 min, fixed: session_seconds is not used |
dc_pergb | gate-us.vaultproxies.com | 777 / 666 | Country | Up to 24 h (session_seconds ≤ 86400) |
mobile_pergb | gate-eu.vaultproxies.com | 8080 / 1080 | Country, ASN | Up to 2 h (session_seconds ≤ 7200), converted to whole minutes |
shared_isp | gate-us.vaultproxies.com | 30 / 31 | Country, IP pinning, via ips, mutually exclusive with sticky | Up to 24 h (session_seconds ≤ 86400), mutually exclusive with ips |
eu_isp | gate-eu.vaultproxies.com | 30 / 31 | Country | None (always rotating) |
ipv6_pergb | gate-us.vaultproxies.com | 30 / 31 | None | None (always rotating) |
ipv6_dc_pergb | gate-us.vaultproxies.com | 30 / 31 | None | Up to 24 h (session_seconds ≤ 86400) |
ipv6_dc_unlim | gate-us.vaultproxies.com | 30 / 31 | None | Up to 24 h (session_seconds ≤ 86400) |
Targeting tokens
Targeting rides inside the proxy username as -key-value pairs appended to the base username. The generator builds these for you when you pass country, state and city; this reference is for hand-built credentials and for anything you expose to your own customers.
ca3ddbbd85591e7f-geo-us-st-california-sess-drfse9co-life-21600| Token | Selects | Example |
|---|---|---|
geo- | Country, ISO-3166 alpha-2 | geo-us |
st- | State or province | st-california |
loc- | City, by name from the locations endpoint | loc-dallas |
reg- | A group of COUNTRIES, not a state | reg-nordics |
pc- | Postal / ZIP code | pc-90001 |
dma- | Metro area (Nielsen DMA) | dma-501 |
gid- | City, by GeoNames id | gid-5368361 |
asn- | Autonomous system number | asn-7922 |
isp- | ISP or mobile carrier | isp-comcast |
tz- | Timezone | tz-america_new_york |
near- | Radius search, lat, long, km | near-34.05N118.24W50 |
ip- | Pin one static IP (dots as underscores) | ip-203_0_113_7 |
sess- | Sticky session id, same exit IP while it lives | sess-a1b2c3d4 |
life- | Session lifetime, in seconds | life-600 |
A plan only honours the tokens its pool can actually act on. Sending one it does not support is an error, not a silent downgrade, so you never end up somewhere you did not ask for.
| Plan | Tokens it honours |
|---|---|
resi_pergb | geo, reg, loc, asn, sess, life (a city by name, sticky up to 3 hours) |
resi_lite_pergb | geo, reg, st, pc, dma, gid, asn, isp, tz, near, sess, life (no loc: a city name is refused, use gid; sticky up to 6 hours) |
mobile_pergb | geo, reg, asn, sess, life |
dc_pergb | geo, reg, sess, life, US-only pool |
shared_isp | geo, ip, sess, life, US-only pool |
ipv6_pergb | None, US-only pool, nothing left to choose |
eu_isp | geo, NL-only pool; no sticky, it rotates regardless of session |
dedicated_isp | None, the IP you were assigned is the targeting |
resi_unlim (Main pool) | geo, loc, asn, sess, life (a catalogued city by name, sticky up to 3 hours) |
resi_unlim (Legacy pool), resi_unlim_budget, dc_unlim | A different username grammar, none of the tokens above apply; see the sticky usernames below, or let generate build them |
GET /api/plans/catalog is public and returns the same per-plan targeting list, alongside each plan's gateway host and ports: read it from your code rather than hard-coding this table.
Residential per-GB comes as two plans on different networks, and they do not offer the same dimensions. On resi_pergb a city is targeted by NAME from the locations endpoint, there is no state, postal, metro, GeoNames, ISP, timezone or radius dimension, and a sticky session holds for at most 3 hours. resi_lite_pergb has those fine-grained dimensions, takes a city only by GeoNames id, and holds a sticky session for up to 6 hours. The catalogue always describes the network serving each plan right now, and the dashboard generator is built from the same response, so a field it does not show is one the live network would refuse. Credentials already issued are never moved between networks.
Sticky usernames, if you build them yourself
The generate endpoint builds these for you and converts session_seconds into the unit each plan expects, which is the reason to use it. If you build usernames by hand instead, copy the shape for your plan exactly: the keyword and the unit both change from plan to plan, and an unknown keyword is ignored rather than refused, so a credential that looks right can quietly hold no session at all.
| Plan | Sticky username | Session length |
|---|---|---|
resi_pergb | user-geo-us-loc-<city>-sess-<id>-life-<seconds> | Seconds, up to 10800 (3 h). The city is optional and must be one the locations endpoint lists |
resi_lite_pergb | user-geo-us-st-<state>-sess-<id>-life-<seconds> | Seconds, up to 21600 (6 h). The state is optional |
pool4_pergb | user-geo-us-sess-<id> | Fixed hold of about 10 minutes, no duration token |
mobile_pergb | user-country-us-session-<id>-time-<minutes> | MINUTES, up to 120 (2 h) |
shared_isp | user-country-us-time-<seconds>-session-<id> | Seconds, up to 86400 (24 h). Or pin one IP with -ip-203_0_113_10, which cannot be combined with a session |
eu_isp | user-country-nl | No sticky sessions: this pool rotates whatever you send |
ipv6_pergb | user | No targeting and no sticky sessions |
resi_unlim (Main pool) | user-geo-us-loc-chicago-sess-<id>-life-<seconds> | Seconds, up to 10800 (3 h) |
resi_unlim (Legacy pool) | user-country-us-session-<8 digits>-time-<minutes> | MINUTES, not seconds, up to 1440 (24 h). The session id must be digits only |
resi_unlim_budget | user-session-<8 digits>-ttl-<seconds>-country-us | Seconds, up to 86400 (24 h). Country is optional |
dc_unlim | user-session-<id>-duration-<seconds> | Seconds, up to 86400 (24 h). The keyword is duration, not ttl |
dedicated_isp | user | The IP you were assigned is the targeting |
Order parameters
Fields accepted by POST /api/reseller/order. services/extend takes service_id, units, time_unit and term_days from the same list.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_key | string | Yes | Any key from GET /api/reseller/categories, e.g. resi_pergb, resi_unlim, dedicated_isp. The live list is under create order. |
units | integer | Yes | Quantity to buy: GB on per-GB plans, IPs on dedicated_isp, and on time-based plans a count of time_unit (hours by default on resi_unlim and resi_unlim_budget, days on dc_unlim). |
time_unit | string | No | Time-based plans only: hour, day, week or month (30 days). Residential Unlimited buys at most 4,320 hours (180 days) per order. |
update_service_id | integer | No | Top up an existing plan instead of creating one. Pass its id; category_key must match it and units is added. See top up. |
pool | string | For dedicated_isp | Required for dedicated_isp: a pool ID from GET /api/reseller/proxy/isp-pools, e.g. ISP_US_SNEAKERS. Orders without it are rejected. On resi_unlim it picks the pool instead: main (every speed) or legacy (400 Mbps only). |
speed | integer | No | resi_unlim only: line speed in Mbps, 200, 400 or 1000 ("1gbps" works too). With neither speed nor pool the order is the Legacy pool at 400 Mbps; a speed without a pool goes to the Main pool. Extending keeps the line's speed and pool. |
term_days | integer | No | dedicated_isp only: a multiple of 30, from 30 to 360 (default 30). Fixed at purchase. On a renewal it is the term added to the plan, and every IP on it keeps the same address. |
addons | object[] | No | ipv6_dc_unlim new orders only: hand-provisioned extras, each { key, location? }. Keys: dedicated_server_1g ($15 / 30 days, needs a location), ipv6_pool_40 ($20 / 30 days) or ipv6_pool_36 ($65 / 30 days), one pool per order. Charged per 30 days of the plan, rounded up, with no loyalty or coupon discount. Provisioned by hand within 1 business day. Prices and locations: GET /api/catalog/addons?plan_key=ipv6_dc_unlim. |
coupon | string | No | Not accepted on the reseller API: wholesale pricing does not combine with coupons, and an order carrying one is refused with 400. |
Error responses
Errors are returned as JSON with an error field and the matching HTTP status code. A few also carry a code to branch on (orders_paused) or extra fields (a refused delete lists what it forfeits). Read the message: it names the rule that was broken.
{
"error": "insufficient balance"
}| Status | Meaning |
|---|---|
200 | Success |
201 | Created: a new order, a top-up or an extension went through |
400 | Bad request: check parameter names, types and the plan's rules. The message says which |
401 | Unauthorized: X-API-Key header missing or invalid |
402 | Insufficient balance for the requested order |
403 | Account suspended, or the key's account is not an approved reseller |
404 | Not found: a category you cannot order, or a service id your account does not own (every /services/* endpoint answers this) |
409 | Cannot be sold right now: new orders for that plan are paused (code orders_paused), or a Residential Unlimited Main-pool line is not available for that long (the message names the longest you can buy). Nothing was charged |
429 | Rate limit exceeded: wait for Retry-After seconds |
500 | Unexpected error. Quote the reference in the message to support. A new order that fails this way has not charged you; a password rotation that fails this way may have changed the credentials without recording them |
502 | The call could not be completed right now. When the message carries a reference nothing was changed and nothing was charged: retry shortly, or quote the reference to support |
Rate limits
The reseller API allows 7,200 requests per minute per API key, an average of 120 a second: enough for production schedulers, provisioning flows and CI jobs without us getting in your way. The public price book is limited per IP instead. Each response carries the standard rate-limit headers:
X-RateLimit-Limit: max requests per windowX-RateLimit-Remaining: remaining requests in this windowX-RateLimit-Reset: seconds until the window resetsRetry-After: on a429, seconds to wait
If you genuinely need more throughput for production scale, message us on /support and we will raise it on your account. Live network status is at /status.
Quick start
Complete workflow: check balance, browse the catalog, place an order, read back the credentials, then generate proxy lines.
# 1. Check your balance
curl -H "X-API-Key: YOUR_API_KEY" "https://vaultproxies.net/api/reseller/balance"
# 2. View available plans and your rates
curl -H "X-API-Key: YOUR_API_KEY" "https://vaultproxies.net/api/reseller/categories"
# 3. Order 5 GB residential
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category_key": "resi_pergb", "units": 5}' \
"https://vaultproxies.net/api/reseller/order"
# 4. List all your services with live credentials
curl -H "X-API-Key: YOUR_API_KEY" "https://vaultproxies.net/api/reseller/services"
# 5. Generate 5 US rotating proxy lines from the new service
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id": 123, "plan_key": "resi_pergb", "country": "US", "extra": {"count": 5}}' \
"https://vaultproxies.net/api/reseller/proxy/generations/create"