Reseller API documentation

Log in

The 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.

Endpoints

PathDescription
GET/accountYour profile, wallet balance, discount and rate limit.
GET/balanceWallet balance only.
GET/transactionsWallet ledger (page, per_page).
GET/catalogAll 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/ordersPlace an order (paid from your wallet).
GET/ordersYour 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}/renewRenew an order for its original duration.
POST/orders/{id}/syncRe-read the proxies from the provider (use while an order is "provisioning").
GET/proxiesAll your proxies (status, order_id, page, per_page, format=txt).
GET/proxies/{id}One proxy.
POST/proxies/{id}/renewRenew a single proxy.
POST/proxies/{id}/rotateRotating proxies: get a fresh IP. Optional body: country (2-letter code).
POST/proxies/{id}/protocolChange the protocol (body: protocol = http | https | socks5) where the supplier allows it.
GET/proxies/{id}/usageBandwidth used / left for GB-based proxies (add ?refresh=1 to bypass the short cache).
POST/webhook/testSends 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

HTTPCodeMeaning
400invalid_jsonThe request body is not valid JSON.
401missing_api_key / invalid_api_keyNo key, or the key is wrong or revoked.
402insufficient_balanceWallet balance is too low. The response includes "required" and "balance".
403not_a_reseller / account_suspended / ip_not_allowed / orders_restrictedAccess is not allowed.
403daily_limit_exceededYour 24-hour API spending limit would be exceeded. The response includes "limit", "spent_24h" and "required".
404product_not_found / order_not_found / proxy_not_foundThe thing you asked for does not exist (or is not yours).
422invalid_order / invalid_reference / renew_failedValidation failed - read "message".
429rate_limitedToo many requests. Wait and retry (see the Retry-After header).
502provider_errorThe upstream supplier failed. Try again shortly.
503out_of_stockThe product is temporarily unavailable.