Reseller APIv1
Ctrl K
Run in PostmanOpenAPI spec Checking…

Wholesale Reseller API

This API lets wholesale proxy resellers buy and manage shared proxies programmatically — using the same engine and pricing our store uses, plus a fixed per-reseller discount. Every request runs through the exact same purchase engine that manual orders use.

Quick start

  1. Create an account and contact support to enable reseller mode and set your discount.
  2. Get your API key from support.
  3. Use the endpoints below — each operation has its own HTTP method and path.
  4. Top up your balance — each purchase or extension is debited from it.

Base URL & authentication

All paths under /api/reseller/v1/* require the X-API-Key header. Keep your key secret — any request with an invalid key is rejected with 401.

Important — every operation has a specific HTTP method. Make sure your client sends the right one: GET to read, POST to create, PATCH to update, DELETE to remove. Sending GET to a POST path returns the list instead of creating a unit.
HeadersCopied!
Base URL: https://wtproxy.com
Header: X-API-Key: <your API key>
Content: Content-Type: application/json
OpenAPI: https://wtproxy.com/api/reseller/v1/openapi.json

Period values

The "period" field accepts five values: 3h (3 hours), 12h (12 hours), 24h (a day), 7d (a week), 30d (a month).

Allowed valuesCopied!
{
"period": "3h"
// or: "12h" | "24h" | "7d" | "30d"
}

Pricing & discount

Prices returned by /pools are the final, post-discount prices — exactly what is debited. For create and extend the amount is debited before execution and fully auto-refunded on failure.

After-discount exampleCopied!
{
"3h": 0.32,
"12h": 0.56,
"24h": 1.04,
"7d": 5.60,
"30d": 20.00
}

Webhook setup (step-by-step)

Webhooks notify your app of every account event (unit created / extended / released, balance low). Setup happens through the API itself:

  1. Stand up a public HTTPS endpoint on your server that accepts a JSON POST.
  2. Call PATCH /api/reseller/v1/webhook with { "url": "<your endpoint>" }. The response includes a secret — store it immediately (not shown again).
  3. On every incoming request: verify the X-WTProxy-Signature header using HMAC-SHA256 of the raw body with the secret. Reject anything that doesn't match.
  4. Return 2xx fast (< 5s). Any error or timeout schedules an exponential retry (1m → 5m → 30m → 2h → 6h, up to 6 attempts).
  5. Inspect the delivery log via GET /api/reseller/v1/webhook/deliveries — shows every event's status (delivered/pending/failed) and reason.

Headers sent with every webhook:

  • X-WTProxy-Event
    Event name, e.g. unit.created.
  • X-WTProxy-Delivery
    Unique delivery id per attempt (use for idempotency on your side).
  • X-WTProxy-Timestamp
    Send time (unix seconds).
  • X-WTProxy-Signature
    sha256=<HMAC of body with secret>. Verify before trusting the payload.

Node.js verification example:

import crypto from 'crypto';

app.post('/wtproxy-events', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.header('X-WTProxy-Signature') || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.WTPROXY_WEBHOOK_SECRET)
    .update(req.body)            // raw body, before JSON.parse
    .digest('hex');
  if (sig !== expected) return res.sendStatus(401);

  const event = JSON.parse(req.body.toString());
  // event = { event: 'unit.created', occurredAt: '...', data: {...} }
  res.sendStatus(200);            // ack within 5s
});

Connection fields — what they mean

  • ip
    The proxy IP address the client connects to.
  • port
    The port number used for the connection.
  • username
    The username for proxy authentication.
  • password
    The password for proxy authentication.
  • protocol
    Protocol: socks5 / http / inject — where inject = HTTP No Auth via IP whitelist.
  • poolId
    Pool (server) ID, e.g. "US-12".
  • provider
    The network provider, e.g. T-Mobile.
  • proxyRef
    The unique proxy reference in the form "PRX-{n}" (site-generated, never the upstream provider's ID).
  • expiresAt
    Expiry date & time (ISO 8601).
Connection stringCopied!
203.0.113.45:51234:u_xxx:p_xxx

Pagination

Endpoints that return large lists (e.g. /units) are paginated. Items come under "data"; paging metadata under the "pagination" object. Control it with the page and pageSize query parameters.

  • page
    Current page number (1-based).
  • pageSize
    Items per page (default 50, max 200).
  • totalItems
    Total number of items across all pages.
  • totalPages
    Total number of pages = ceil(totalItems / pageSize).
  • hasNext
    true if a next page exists.
  • hasPrev
    true if a previous page exists.
RequestCopied!
GET /api/reseller/v1/units?page=2&pageSize=20
ResponseCopied!
{
"data": [ /* … units … */ ],
"pagination": {
"page": 2, "pageSize": 20,
"totalItems": 47, "totalPages": 3,
"hasNext": true, "hasPrev": true
}
}

Error handling

Every error returns a uniform "error" object. Branch on error.type and error.code (both stable, machine-readable); error.message is for display only. Each error carries a requestId — quote it when contacting support.

  • authentication_error401
    Missing or invalid API key.
  • permission_error403
    The account lacks reseller permission.
  • invalid_request_error400
    A malformed body, field, or value.
  • not_found_error404
    The requested resource does not exist.
  • insufficient_balance_error402
    Balance below the required amount (see error.required).
  • rate_limit_error429
    Request rate limit exceeded.
  • service_error5xx
    A temporary service error — retry.
ResponseCopied!
{
"error": {
"type": "insufficient_balance_error",
"code": "insufficient_balance",
"message": "Your balance is below the required amount.",
"documentationUrl": "https://wtproxy.com/api-docs#errors",
"requestId": "req_01HQX9ABCDEF"
}
}
Catalog
GET/api/reseller/v1/pools

List available pools

Returns every available pool (Pro only), with all five discounted period prices. Filterable by provider or country.

Query parameters

  • providerstringoptional
    Optional — filter by carrier (e.g. "T-Mobile", "Verizon", "AT&T").
  • countrystringoptional
    Optional — filter by country slug.
RequestCopied!
GET /api/reseller/v1/pools HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"data": [
{
"poolId": "US-1",
"provider": "T-Mobile",
"country": "US",
"state": "california",
"rotation": "30m",
"available": true
}
],
"prices": { "3h":0.32, "12h":0.56, "24h":1.04, "7d":5.6, "30d":20 }
}
GET/api/reseller/v1/pools/{poolId}

Single pool detail

Returns one pool's detail with its own discounted prices.

Path parameters

  • poolIdstringrequired
    Pool ID (e.g. "US-1").
RequestCopied!
GET /api/reseller/v1/pools/US-1 HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"poolId": "US-1",
"provider": "T-Mobile",
"country": "US",
"state": "california",
"rotation": "30m",
"available": true,
"prices": { "3h":0.32, "12h":0.56, "24h":1.04, "7d":5.6, "30d":20 }
}
Errors
  • 401X-API-Key header is missing or invalid.
  • 404Pool does not exist or is unavailable.
GET/api/reseller/v1/prices

Price schedule

Returns the five period prices (post-discount) — quick lookup separate from the pool list.

RequestCopied!
GET /api/reseller/v1/prices HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{ "prices": { "3h":0.32, "12h":0.56, "24h":1.04, "7d":5.6, "30d":20 } }
Errors
  • 401X-API-Key header is missing or invalid.
GET/api/reseller/v1/providers

List providers

Returns the distinct carriers in the catalogue (T-Mobile, Verizon, AT&T, …) with the number of pools per provider. Use this to power a carrier filter in your UI.

RequestCopied!
GET /api/reseller/v1/providers HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"data": [
{ "provider": "AT&T", "poolCount": 1 },
{ "provider": "T-Mobile", "poolCount": 16 },
{ "provider": "Verizon", "poolCount": 20 }
]
}
Provisioning
GET/api/reseller/v1/units

List your units (paginated)

Returns the proxies your account owns, sorted by poolId. Supports pagination and filters.

Query parameters

  • includeExpiredbooleanoptional
    Optional — true to also include expired units.
  • statusstringoptional
    Optional — exact status filter (ACTIVE / EXPIRED / RELEASED).
  • poolIdstringoptional
    Optional — only units from this pool.
  • expiringWithinHoursintegeroptional
    Optional — only units expiring within N hours.
  • pageintegeroptional
    Optional — page number (default 1).
  • pageSizeintegeroptional
    Optional — page size (default 50, max 200).
RequestCopied!
GET /api/reseller/v1/units HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"data": [
{
"proxyRef": "PRX-12345",
"poolId": "US-1",
"provider": "T-Mobile",
"country": "US",
"state": "california",
"rotation": "30m",
"ip": "203.0.113.45",
"port": 51234,
"protocol": "socks5",
"credentials": { "username": "u_xxx", "password": "p_xxx" },
"status": "ACTIVE",
"createdAt": "2026-05-10T09:00:00.000Z",
"expiresAt": "2026-06-10T09:00:00.000Z",
"expiresIn": 2592000,
"swapCount": 1
}
],
"pagination": {
"page": 1,
"pageSize": 50,
"totalItems": 47,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}
Errors
  • 401X-API-Key header is missing or invalid.
GET/api/reseller/v1/units/{proxyRef}

Single unit detail

Returns the details of a specific proxy you own.

Path parameters

  • proxyRefstringrequired
    The proxy reference (e.g. "PRX-9").
RequestCopied!
GET /api/reseller/v1/units/PRX-12345 HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"proxyRef": "PRX-9",
"poolId": "US-1",
"provider": "T-Mobile",
"country": "US",
"state": "california",
"rotation": "30m",
"ip": "108.61.144.196",
"port": 21798,
"protocol": "socks5",
"credentials": { "username": "u_xxx", "password": "p_xxx" },
"status": "ACTIVE",
"createdAt": "2026-05-17T12:16:21.714Z",
"expiresAt": "2026-05-17T15:16:21.714Z",
"expiresIn": 8400,
"swapCount": 0
}
Errors
  • 401X-API-Key header is missing or invalid.
  • 404Unit does not exist or is not owned by you.
POST/api/reseller/v1/units

Create a new unit

Buys a new proxy from the chosen pool. The discounted price is debited from your balance, and auto-refunded on failure. Send an Idempotency-Key header (a UUID) to guarantee a retry after a network failure never double-charges or double-provisions.

Request body fields (JSON)

  • poolIdstringrequired
    The pool ID from /pools (e.g. "US-12").
  • periodstringrequired
    Period: 3h, 12h, 24h, 7d, 30d.
  • protocolstringoptional
    Optional — socks5 (default) or http (both use username/password) or inject (HTTP No Auth, IP whitelisted).
  • credentialsobjectoptional
    Optional — { username, password } for custom credentials.
  • allowedIpsstring[]optional
    Required when protocol="inject" — at creation it must contain exactly ONE IP. Additional IPs are added later via PATCH on the unit.
RequestCopied!
POST /api/reseller/v1/units HTTP/1.1
Host: wtproxy.com
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{
"poolId": "US-1",
"period": "30d",
"protocol": "socks5"
}
ResponseCopied!
{
"proxyRef": "PRX-12345",
"poolId": "US-1",
"provider": "T-Mobile",
"country": "US",
"state": "california",
"rotation": "30m",
"ip": "203.0.113.45",
"port": 51234,
"protocol": "socks5",
"credentials": { "username": "u_xxx", "password": "p_xxx" },
"status": "ACTIVE",
"createdAt": "2026-05-17T09:00:00.000Z",
"expiresAt": "2026-06-16T09:00:00.000Z",
"expiresIn": 2592000
}
Errors
  • 400Malformed JSON body.
  • 401X-API-Key header is missing or invalid.
  • 403Reseller mode is disabled for this account.
  • 400Invalid protocol value.
  • 400inject requires at least one allowedIps entry.
  • 402Balance below the required amount.
  • 404The pool does not exist or is unavailable.
  • 503Upstream service unavailable (balance is auto-refunded).
POST/api/reseller/v1/units/{id}/extend

Extend a unit

Extends a proxy by another period. The discounted price is debited and refunded on failure.

Path parameters

  • idstringrequired
    The proxy reference (e.g. "PRX-12345").

Request body fields (JSON)

  • periodstringrequired
    Period to add: 3h, 12h, 24h, 7d, 30d.
RequestCopied!
POST /api/reseller/v1/units/PRX-12345/extend HTTP/1.1
Host: wtproxy.com
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{ "period": "7d" }
ResponseCopied!
{
"proxyRef": "PRX-12345",
"expiresAt": "2026-06-23T09:00:00.000Z",
"extended": true
}
POST/api/reseller/v1/units/{id}/swap

Swap pool

Moves the proxy to another pool while keeping its remaining time. No balance is charged.

Path parameters

  • idstringrequired
    The proxy reference (e.g. "PRX-12345").

Request body fields (JSON)

  • newPoolIdstringrequired
    The ID of the new pool.
RequestCopied!
POST /api/reseller/v1/units/PRX-12345/swap HTTP/1.1
Host: wtproxy.com
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{ "newPoolId": "EG-3" }
ResponseCopied!
{
"proxyRef": "PRX-12345",
"poolId": "EG-3",
"provider": "Vodafone",
"ip": "198.51.100.7",
"port": 50880,
"protocol": "socks5",
"credentials": { "username": "u_xxx", "password": "p_xxx" },
"expiresAt": "2026-06-23T09:00:00.000Z"
}
PATCH/api/reseller/v1/units/{id}

Modify a unit

Updates credentials, description, or the allowed-IP list.

Path parameters

  • idstringrequired
    The proxy reference (e.g. "PRX-12345").

Request body fields (JSON)

  • credentialsobjectoptional
    Optional — new { username, password }.
  • descriptionstringoptional
    Optional — a new description.
  • allowedIpsstring[]optional
    Optional — a new allowed-IP list.
RequestCopied!
PATCH /api/reseller/v1/units/PRX-12345 HTTP/1.1
Host: wtproxy.com
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{
"credentials": { "username": "new_user", "password": "new_pass" }
}
ResponseCopied!
{
"proxyRef": "PRX-12345",
"modified": true
}
DELETE/api/reseller/v1/units/{id}

Release a unit

Permanently deletes the proxy. No balance is refunded for a manual release.

Path parameters

  • idstringrequired
    The proxy reference (e.g. "PRX-12345").
RequestCopied!
DELETE /api/reseller/v1/units/PRX-12345 HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"proxyRef": "PRX-12345",
"removed": true
}
Account
GET/api/reseller/v1/me

Account snapshot

Everything you need on session start in one round-trip: balance, discount, unit counts, prices, webhook status.

RequestCopied!
GET /api/reseller/v1/me HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"email": "[email protected]",
"balanceUsd": 142.50,
"discountPercent": 20,
"resellerEnabled": true,
"units": { "active": 12, "total": 47 },
"prices": { "3h":0.32, "12h":0.56, "24h":1.04, "7d":5.6, "30d":20 },
"webhook": { "url": "https://your.app/webhook", "enabled": true }
}
Errors
  • 401X-API-Key header is missing or invalid.
  • 403Reseller mode is disabled for this account.
GET/api/reseller/v1/account

Query balance

Returns the current balance and the discount rate applied to your purchases.

RequestCopied!
GET /api/reseller/v1/account HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"balanceUsd": 142.50,
"discountPercent": 20,
"resellerEnabled": true
}
Webhooks
GET/api/reseller/v1/webhook

Read current webhook config

Returns the currently configured webhook URL, the HMAC secret, and the enabled flag. If no webhook is set, all fields are null/false.

RequestCopied!
GET /api/reseller/v1/webhook HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"url": "https://your.app/wtproxy-events",
"secret": "whs_abc123…",
"enabled": true
}
Errors
  • 401X-API-Key header is missing or invalid.
GET/api/reseller/v1/webhook/deliveries

Webhook delivery log

Lists recent webhook delivery attempts (success/failure/pending retry) for debugging. Newest first. Supports filtering by status and event.

Query parameters

  • pageintegeroptional
    Page number (default 1).
  • pageSizeintegeroptional
    Items per page (default 25, max 100).
  • statusstringoptional
    Filter by status: PENDING / DELIVERED / FAILED.
  • eventstringoptional
    Filter by event type (e.g., unit.created, unit.released).
RequestCopied!
GET /api/reseller/v1/webhook/deliveries HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{
"data": [
{
"id": "wdl_abc123",
"event": "unit.created",
"url": "https://your.app/wtproxy-events",
"status": "DELIVERED",
"attempts": 1,
"maxAttempts": 5,
"responseStatus": 200,
"lastError": null,
"nextAttemptAt": null,
"createdAt": "2026-05-22T18:30:00Z",
"deliveredAt": "2026-05-22T18:30:01Z"
}
],
"pagination": { "page": 1, "pageSize": 25, "total": 47, "totalPages": 2 }
}
Errors
  • 401X-API-Key header is missing or invalid.
PATCH/api/reseller/v1/webhook

Configure webhook

Sets the webhook URL for account events (create / extend / release / low balance). The HMAC secret is returned once — use it to verify the X-WTProxy-Signature header on incoming requests. Pass url=null to disable.

Request body fields (JSON)

  • urlstringoptional
    HTTPS URL to receive events, or null to disable.
RequestCopied!
PATCH /api/reseller/v1/webhook HTTP/1.1
Host: wtproxy.com
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{ "url": "https://your.app/wtproxy-events" }
ResponseCopied!
{
"url": "https://your.app/wtproxy-events",
"secret": "whs_abc123…",
"enabled": true
}
Errors
  • 401X-API-Key header is missing or invalid.
  • 400Invalid URL.
DELETE/api/reseller/v1/webhook

Disable webhook

Removes the webhook URL and secret. No further notifications will be delivered until you set it again via PATCH.

RequestCopied!
DELETE /api/reseller/v1/webhook HTTP/1.1
Host: wtproxy.com
X-API-Key: YOUR_API_KEY
ResponseCopied!
{ "enabled": false }
Errors
  • 401X-API-Key header is missing or invalid.