Reseller API documentation
Log inThe reseller API lets approved resellers browse the catalog, place and renew orders and read their proxies from their own website, panel or bot. Apply from My account → Reseller API; after an admin approves you, you can create an API key there.
Basics
Base URL: https://proxysold.com/api/v1
Authenticate every request with your key: Authorization: Bearer YOUR_API_KEY (or the header X-API-Key). Keep the key secret and only call the API from your server - never from a browser or an app you distribute. You can restrict a key to your server IPs in your account.
- Responses are JSON. Success:
{"success":true,"data":...}. Error:{"success":false,"error":{"code":"...","message":"..."}}. - Send POST bodies as JSON (
Content-Type: application/json) or as a normal form. - Only GET and POST are used. All amounts are USD. Times are ISO 8601 (UTC).
- List endpoints accept
pageandper_page(max 100) and returnmeta.total. - Every key has a per-minute rate limit (see your account). Headers
X-RateLimit-LimitandX-RateLimit-Remainingare sent. - Your reseller discount applies to API orders and API renewals. It can differ per product - the catalog already shows your price.
- If a daily spending limit is set on your account, API orders and renewals stop with
daily_limit_exceededonce the last 24 hours of API spending reach it.
Endpoints
| Path | Description | |
|---|---|---|
| GET | /account | Your profile, wallet balance, discount and rate limit. |
| GET | /balance | Wallet balance only. |
| GET | /transactions | Wallet ledger (page, per_page). |
| GET | /catalog | All active products with stock status and the lowest price (your reseller price). |
| GET | /catalog/{slug} | One product: countries, prices per duration for ONE IP, ISP / state requirements. Add ?country=US for ISP, state and pack lists. |
| POST | /orders | Place an order (paid from your wallet). |
| GET | /orders | Your orders (status, page, per_page). |
| GET | /orders/{id} | One order with its proxies. Add ?format=txt for ip:port:user:pass lines. |
| POST | /orders/{id}/renew | Renew an order for its original duration. |
| POST | /orders/{id}/sync | Re-read the proxies from the provider (use while an order is "provisioning"). |
| GET | /proxies | All your proxies (status, order_id, page, per_page, format=txt). |
| GET | /proxies/{id} | One proxy. |
| POST | /proxies/{id}/renew | Renew a single proxy. |
| POST | /proxies/{id}/rotate | Rotating proxies: get a fresh IP. Optional body: country (2-letter code). |
| POST | /proxies/{id}/protocol | Change the protocol (body: protocol = http | https | socks5) where the supplier allows it. |
| GET | /proxies/{id}/usage | Bandwidth used / left for GB-based proxies (add ?refresh=1 to bypass the short cache). |
| POST | /webhook/test | Sends a test event to your webhook URL. |
Quick start
1. Check your balance
curl https://proxysold.com/api/v1/balance \ -H "Authorization: Bearer YOUR_API_KEY"
2. Browse the catalog
curl https://proxysold.com/api/v1/catalog -H "Authorization: Bearer YOUR_API_KEY" curl "https://proxysold.com/api/v1/catalog/PRODUCT_SLUG?country=US" -H "Authorization: Bearer YOUR_API_KEY"
3. Place an order
Fields: product (slug), country (code), quantity, duration_days, protocol (http / https / socks5), isp and region when the country requires them, ips (whitelist products), and an optional reference.
Use a unique reference for every order. If your request times out and you send it again with the same reference, you get the same order back and are never charged twice (the response contains "duplicate": true).
curl -X POST https://proxysold.com/api/v1/orders \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product":"PRODUCT_SLUG","country":"US","quantity":5,"duration_days":30,"protocol":"http","reference":"shop-order-1001"}'
Status 201 = delivered, the proxies are in data.proxies. Status 202 = accepted but not ready yet (status is pending, provisioning or waiting for an admin): poll GET /orders/{id} every 10-30 seconds. If the order cannot be fulfilled it is refunded to your wallet automatically.
{
"success": true,
"data": {
"id": 1842, "reference": "shop-order-1001", "status": "active",
"product": {"slug": "...", "name": "..."}, "country": "US", "quantity": 5, "duration_days": 30,
"price_paid": 8.5, "discount": 1.5, "currency": "USD",
"created_at": "2026-10-26T10:00:00+00:00", "expires_at": "2026-11-25T10:00:00+00:00",
"proxies": [
{"id": 9001, "ip": "203.0.113.5", "port": 8000, "username": "u1", "password": "p1", "protocol": "http",
"country": "US", "status": "active", "line": "203.0.113.5:8000:u1:p1"}
]
}
}
4. Renew
curl -X POST https://proxysold.com/api/v1/orders/1842/renew -H "Authorization: Bearer YOUR_API_KEY"
PHP example
$ch = curl_init('https://proxysold.com/api/v1/orders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['product' => 'PRODUCT_SLUG', 'country' => 'US', 'quantity' => 5,
'duration_days' => 30, 'reference' => 'shop-order-1001']),
]);
$res = json_decode(curl_exec($ch), true);
if (!$res['success']) { echo $res['error']['code'] . ': ' . $res['error']['message']; }
Webhooks
Set a webhook URL in My account → Reseller API and we will POST a JSON event to it when one of your API orders changes. No more polling.
Events: order.active (proxies delivered), order.failed (not fulfilled, refunded when it was paid from the wallet), order.renewed, order.expired and webhook.test. The data field has the same shape as GET /orders/{id}.
{
"id": "evt_8841", "event": "order.active", "created_at": "2026-10-26T10:00:05+00:00",
"data": { "id": 1842, "reference": "shop-order-1001", "status": "active", "proxies": [ ... ] }
}
Your server must answer with a 2xx status within 8 seconds. Otherwise we retry after 1 min, 5 min, 30 min, 2 h and 6 h, then give up. The same event can arrive more than once, so use id to ignore duplicates. The URL must be public https.
Verify the signature. Each request has the headers X-Webhook-Timestamp and X-Webhook-Signature (sha256= followed by HMAC-SHA256 of timestamp + "." + raw body with your signing secret). Reject requests with an old timestamp (for example older than 5 minutes).
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$ok = abs(time() - (int)$ts) < 300
&& hash_equals('sha256=' . hash_hmac('sha256', $ts . '.' . $raw, 'YOUR_SIGNING_SECRET'), $sig);
if (!$ok) { http_response_code(401); exit; }
$event = json_decode($raw, true);
http_response_code(200);
// Node.js (Express, use express.raw({type: 'application/json'}))
const crypto = require('crypto');
const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(ts + '.' + req.body).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
Order statuses
pending / processing (being placed), provisioning (placed with the supplier, proxies not ready), active, expired, suspended, failed, refunded. When awaiting_admin is true the product needs a manual approval or manual delivery by our team.
Errors
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_json | The request body is not valid JSON. |
| 401 | missing_api_key / invalid_api_key | No key, or the key is wrong or revoked. |
| 402 | insufficient_balance | Wallet balance is too low. The response includes "required" and "balance". |
| 403 | not_a_reseller / account_suspended / ip_not_allowed / orders_restricted | Access is not allowed. |
| 403 | daily_limit_exceeded | Your 24-hour API spending limit would be exceeded. The response includes "limit", "spent_24h" and "required". |
| 404 | product_not_found / order_not_found / proxy_not_found | The thing you asked for does not exist (or is not yours). |
| 422 | invalid_order / invalid_reference / renew_failed | Validation failed - read "message". |
| 429 | rate_limited | Too many requests. Wait and retry (see the Retry-After header). |
| 502 | provider_error | The upstream supplier failed. Try again shortly. |
| 503 | out_of_stock | The product is temporarily unavailable. |
