Operations that spend money
Orders and renewals require an Idempotency-Key header; retrying with the same key never charges you twice.
Idempotency-Key
POST /orders and POST /orders/{id}/renew require a unique Idempotency-Key header for each new order or renewal. On a timeout it is safe to retry with the same value: the completed request is returned again (meta.idempotent_replay: true) and you are never charged twice.
Idempotency-Key: 3f7a1c9e-2b48-4d51-9c3a-8e6f0d215b47Generate the key once
Generate a UUID for each new order or renewal and keep it in a variable.
On a timeout, retry with the same key
If no response came back, send the request again with the same key. Generating a new key for the retry opens a second order.
409 and Retry-After
A retry that arrives while the first request is still being processed gets 409 conflict and Retry-After; wait, then retry with the same key.
import { randomUUID } from "node:crypto";
const key = randomUUID(); // the SAME value on every retry
async function createOrder(body) {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch("https://api.proxynet.io/api/v1/orders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PROXYNET_TOKEN}`,
"Idempotency-Key": key,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (res.status === 409 && res.headers.get("retry-after")) {
await new Promise((r) => setTimeout(r, Number(res.headers.get("retry-after")) * 1000));
continue;
}
return res.json();
}
}import os, time, uuid, requests
key = str(uuid.uuid4()) # the SAME value on every retry
def create_order(body):
for _ in range(3):
res = requests.post(
"https://api.proxynet.io/api/v1/orders",
headers={
"Authorization": f"Bearer {os.environ['PROXYNET_TOKEN']}",
"Idempotency-Key": key,
},
json=body,
)
if res.status_code == 409 and "Retry-After" in res.headers:
time.sleep(int(res.headers["Retry-After"]))
continue
return res.json()When a key is released
- A key is released only if the attempt definitely did not charge you: a
4xxrejection, or a provider error whose charge was refunded (details.refunded: true). In that case the same key starts a new attempt. - A key is for a single operation. Sending the same key with a different body (targets, name and options included), or using it for another order or renewal, returns
400 invalid_request. A key that opened an order is not accepted for a renewal, and a key used for a renewal is not accepted for an order. - A
409 conflictwithdetails.order_idmeans the order opened with that key is no longer active (it failed before an automatic refund could be made, or it was cancelled). Use a new key; if you were charged, contact support.
Is the order ready
meta.ready tells you whether the order is already active, in a replayed response too. It is false for a pre-order, a scheduled activation or a provider delay, andmeta.warning is filled in. Don't put the order to use yet; poll GET /orders/{id} until state is active.
Credentials
The username and password are optional. If you don't send them, the system generates them; they are returned in the response if the token also has proxies:read. Choosing them yourself requires your plan to allow it: check the plan.custom_credentials field in the /me response.
Order fields by type
✓ accepted, ✓* required, — not used on this type; the value in parentheses is the default used when the field is not sent. Unknown fields are rejected; a typo is never silently ignored.
| Field | ISP / Datacenter | Gaming | Residential / Mobile |
|---|---|---|---|
orderType | ✓* | ✓* | ✓* |
locationId | ✓* | ✓* | — |
quantity | ✓* | ✓* | — |
unlimitedAccess / targetUrls | ✓* | — | — |
protocol | ✓ (auto) | ✓ (socks5) | — |
highConnection | ✓ | ✓ | ✓ |
extraIpWhitelist | ✓ | ✓ | — |
nonSequentialIps | ✓ | ✓ | — |
highSpeed | ✓ | ✓ | — |
countryCode | — | — | ✓ |
gbLimit | — | — | ✓ |
username / password / gateName | ✓ | ✓ | ✓ |
Settings changes
Settings changes such as the service name and traffic limit spend no money and are made with a separate scope (proxies:write). They don't require an Idempotency-Key.