Reseller API

Wholesale access for agencies and resellers. Create sub-accounts for your own customers, provision subscriptions against your reseller balance at wholesale prices, generate proxy lists, and track usage and live connections, all over a REST API under one approved reseller account.

i
This is a separate API. The Reseller API uses its own base URL and requires an approved reseller account. If you only need to manage your own account (whitelist, proxy-list export, usage stats), use the Public API instead.

Base URL

All Reseller API requests go to:

https://dashboard.proxyomega.com/api/reseller/v1

Every endpoint path on this page is relative to this base. All responses are application/json. A no-auth test sandbox is available under /dev.

Getting access

Three steps stand between a regular account and live Reseller API access:

  1. Apply for a reseller account. Apply from the dashboard. Applications are reviewed and approved manually. Learn more at proxyomega.com/reseller-program.
  2. Complete identity verification (KYC). Every production endpoint except the /kyc/* and /balance/* routes returns 401 until your identity is verified. Start verification via the API (see Identity verification) or in the dashboard.
  3. Fund your reseller balance. Provisioning is wallet-based: every purchase is charged to your reseller balance at wholesale price. Move funds from your main account balance with POST /balance/transfer. The first transfer requires verified KYC and activates the account.

Authentication

Send your API key in the X-API-Key header on every request:

X-API-Key: YOUR_API_KEY

A bearer token is also accepted, so Authorization: Bearer YOUR_API_KEY works with the same key. The key is your ProxyOmega account API key, viewable and regenerable in the dashboard once your reseller account is approved.

curl https://dashboard.proxyomega.com/api/reseller/v1/balance \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
i
One key, two jobs. Your account API key is also your account's proxy password. Regenerating the key rotates both at once. Keep it secret, send it over HTTPS only, and never put it in query strings, client-side code, or version control.

Responses & envelope

Every endpoint wraps its payload in the same envelope. Successful calls return:

{
  "success": true,
  "data": { },
  "message": "Optional human-readable note"
}

Errors return "success": false with an explanation:

{
  "success": false,
  "error": "Description of what went wrong"
}

Always check success before reading data. Validation failures may include a per-field errors object.

Rate limits

The default limit is 100 requests per minute over a sliding 60-second window. Exceeding it returns 429. Every response carries the current state in headers:

HeaderMeaning
X-RateLimit-LimitYour requests-per-minute allowance
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-UsedRequests used in the current window
X-RateLimit-ResetUnix timestamp when the window resets

Account, balance & transactions

MethodEndpointPurpose
GET/API version plus a summary of your reseller ID, tier, and balance
GET/balanceBalance, tier, discount, monthly spending, and tier thresholds
POST/balance/transferMove funds from your main account balance to your reseller balance
GET/transactionsPaginated ledger of every charge and credit on the reseller balance

Check your balance

curl https://dashboard.proxyomega.com/api/reseller/v1/balance \
  -H "X-API-Key: YOUR_API_KEY"
{
  "success": true,
  "data": {
    "balance": 250.00,
    "tier": "silver",
    "current_discount": "15%",
    "monthly_spending": 1240.50,
    "spending_reset_date": "2026-08-01",
    "next_tier": "gold",
    "amount_to_next_tier": 759.50,
    "minimum_balance_required": 100.00
  }
}

Your tier (bronze, silver, gold, platinum) is driven by monthly spending, and the tier's discount is already applied to the wholesale prices you see in the catalog and pay at provisioning time.

Fund the reseller balance

POST /balance/transfer with a JSON body of {"amount": 250}. Transfers are between $100 (minimum, and the first transfer activates your account) and $10,000 per transfer, and are atomic: either the full amount moves or nothing does.

curl -X POST https://dashboard.proxyomega.com/api/reseller/v1/balance/transfer \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 250}'

The response includes new_reseller_balance, new_main_balance, and is_first_transfer. A first transfer without verified KYC returns 403 with kyc_required: true; an amount your main balance cannot cover returns 400 with the available, requested, and shortfall figures.

Transaction history

GET /transactions accepts page (default 1), limit (10 to 100, default 20), and an optional type filter: deposit, provision, refund, or adjustment (renewal and upgrade rows also appear in the data). Each row carries the amount, balance before and after, the related sub-account and subscription, and a description, plus a pagination block.

Identity verification (KYC)

The /kyc/* routes work before verification so you can complete it entirely over the API. Verification uses a hosted flow: you submit a government document (passport, driving licence, or ID card) and a matching selfie at a secure URL, then poll the status.

MethodEndpointPurpose
GET/kyc/statusCurrent verification status and attempts remaining
POST/kyc/business-infoSet company_name (required), company_address (required), tax_id (optional)
POST/kyc/start-verificationCreate a verification session; returns a hosted url to complete it

POST /kyc/start-verification (empty body) returns session_id, url, status: "pending", and expires_at. Open the URL to complete verification, then poll GET /kyc/status. Status values: not_started, pending, processing, verified, rejected, expired. You get a maximum of 3 attempts; after that the endpoint returns 403 and you should contact support.

Products, capacity & locations

MethodEndpointPurpose
GET/productsWholesale catalog with retail and wholesale prices per plan
GET/capacityPer-tier availability pre-flight for Budget Unlimited
GET/geographic/countriesCountries available for a product (product_type required)
GET/geographic/regionsRegions within a country (Residential/ISP and Mobile)
GET/geographic/citiesCities within a country or region

Catalog

GET /products returns your tier, discount_percentage, and per-product pricing. Each pricing row includes both retail_price and wholesale_price with your tier discount already applied. The catalog covers:

  • unlimited (Budget Unlimited): 5, 15, 25, 50, or 100 ports, for 1_day, 7_days, or 30_days
  • ipv6: 100, 250, 500, or 1000 threads, same three durations
  • platinum (Residential/ISP) and mobile: pay-as-you-go bandwidth tiers from 1 GB to 1000 GB
i
Premium Unlimited pricing is not in the catalog. Premium Unlimited can be provisioned through the API (see Provisioning) but does not appear in GET /products. Contact [email protected] or check your dashboard for Premium wholesale pricing.

Capacity

GET /capacity is a pre-flight check before selling Budget Unlimited: it returns {"tiers": [{"ports": 5, "available": ...}, ...], "as_of": "..."} so you can confirm a port tier is available before provisioning. If a tier is temporarily unavailable at purchase time, provisioning returns 409.

Locations

GET /geographic/countries?product_type=platinum lists countries as {code, name} pairs, plus supports_regions and supports_cities flags. product_type is required and accepts platinum, mobile, ipv6, unlimited, or premium_unlimited. For platinum and mobile the first entry has an empty code, meaning random/default.

GET /geographic/regions?product_type=platinum&country=US lists regions (Residential/ISP and Mobile only). GET /geographic/cities?product_type=platinum&country=US&region=California lists cities; region is optional, and cities are also available for premium_unlimited (without region).

Sub-accounts

Sub-accounts are the accounts you hand to your own customers. Each gets its own proxy username and password, its own subscriptions, whitelist, and usage history.

MethodEndpointPurpose
GET/sub-accountsList sub-accounts with subscription and usage summaries
POST/sub-accountsCreate a sub-account
GET/sub-accounts/{id}Full detail: subscriptions, bandwidth purchases, whitelist, proxy credentials
PUT/sub-accounts/{id}Update email, label, external_id, or status (active | suspended)
DELETE/sub-accounts/{id}Soft-delete; all active subscriptions are cancelled
POST/sub-accounts/{id}/regenerate-passwordRotate the sub-account's proxy password/API key

Create a sub-account

username is required (3 to 30 characters, letters, digits, and underscores). external_id, email, and label are optional and yours to use for reconciliation with your own systems.

curl -X POST https://dashboard.proxyomega.com/api/reseller/v1/sub-accounts \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "client1",
    "email": "[email protected]",
    "label": "Client A"
  }'
{
  "success": true,
  "data": {
    "id": 512,
    "username": "res_42_client1",
    "password": "a1b2c3d4e5f6a7b8",
    "api_key": "a1b2c3d4e5f6a7b8",
    "external_id": null,
    "email": "[email protected]",
    "label": "Client A",
    "status": "active",
    "proxy_auth": {
      "format": "username:api_key",
      "example": "res_42_client1:[email protected]:10000"
    }
  }
}

Note the returned username is prefixed with res_<your-reseller-id>_. White-label accounts keep the username exactly as submitted; contact support about white-label. The password and api_key are the same value, and this value is what the sub-account uses as its proxy password. Duplicate usernames return 409.

i
Hosts and credentials in the examples are placeholders. Always connect with the exact host, ports, username, and password returned by the API for each subscription.

List and inspect

GET /sub-accounts accepts page, limit (10 to 100, default 20), status (active | suspended | deleted), search (matches username, label, email, or external ID), and has_active_subscription=1. Each row includes counts of active subscriptions and bandwidth purchases, whitelisted IPs, per-product summaries, and 24-hour request/bandwidth stats.

GET /sub-accounts/{id} returns everything about one sub-account: each subscription with its proxy connection details (host, port or port range, username, password, ready-to-use full_proxy string), each pay-as-you-go bandwidth purchase with live used/available GB, and the whitelist.

Sub-account, subscription, whitelist, and proxy-list routes accept either the numeric sub-account id or its username in the path. The analytics and connections routes require the numeric id.

Rotate credentials

POST /sub-accounts/{id}/regenerate-password mints a fresh key. The proxy password and API key rotate together, and the new credential is live on the proxy network within about a minute (usually seconds). Requests to a deleted sub-account return 410.

IP whitelists

Each sub-account can whitelist up to 10 IPs (IPv4 or IPv6). Whitelisted IPs can use the proxies without password authentication.

MethodEndpointPurpose
GET/sub-accounts/{id}/whitelistList whitelist entries
POST/sub-accounts/{id}/whitelistAdd an IP: {"ip_address": "198.51.100.7", "label": "Client server"}
DELETE/sub-accounts/{id}/whitelist/{ip_id}Remove an entry by its id

Adding an already-whitelisted IP returns 409; the 11th IP returns 400.

Provisioning subscriptions

POST /sub-accounts/{id}/subscriptions provisions a product for a sub-account and charges your reseller balance at your wholesale price. The body depends on the product:

product_typeRequired fieldsAccepted values
unlimitedduration, ports1_day | 7_days | 30_days; ports 5 | 15 | 25 | 50 | 100
ipv6duration, threadsSame durations; threads 100 | 250 | 500 | 1000
platinumgb1 | 5 | 15 | 25 | 50 | 100 | 150 | 200 | 500 | 1000
mobilegbSame GB tiers
premium_unlimitedduration, speed_mbps, location_idMbps 200 | 250 | 400 | 500 | 600 | 750 | 800 | 1000
curl -X POST https://dashboard.proxyomega.com/api/reseller/v1/sub-accounts/512/subscriptions \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product_type": "unlimited",
    "duration": "30_days",
    "ports": 25
  }'
{
  "success": true,
  "data": {
    "subscription_id": 90411,
    "product_type": "unlimited",
    "wholesale_price": 100.00,
    "balance_remaining": 400.00,
    "date_expiry": "2026-08-09T14:02:11+00:00",
    "status": "active",
    "credentials": {
      "host": "203.0.113.10",
      "port_range": "10000-10024",
      "username": "res_42_client1",
      "password": "a1b2c3d4e5f6a7b8",
      "full_proxy": "http://res_42_client1:[email protected]:10000"
    }
  }
}

New subscriptions return 201. Insufficient balance returns 400 with the required and available amounts. Credentials become active on the proxy network within about a minute.

i
Same config = renewal, not a duplicate. If the sub-account already has an active unlimited or ipv6 subscription with the same configuration, the call extends that subscription instead of creating a second one: it returns 200 with "action": "renewed" and the new expiry. To change size, use the upgrade endpoint.

Pay-as-you-go bandwidth (Residential/ISP and Mobile)

platinum and mobile orders return a purchase_id and gb_added rather than an expiring subscription; the bandwidth does not expire. If provisioning fails on our side, the charge is automatically refunded to your reseller balance.

Premium Unlimited

Premium Unlimited is a dedicated, pending-fulfilment product. The order is accepted with 201 and box_status: "pending"; the connection host stays null until the dedicated server is ready, which is often near-instant and can take up to 6 hours. Orders require a location_id; contact [email protected] for the currently available Premium locations and pricing.

Connection ports by product

ProductPorts on the returned host
Budget Unlimited (unlimited)10000 to 10000 + ports - 1 (one rotating IP per port)
IPv6 (ipv6)9000
Residential/ISP (platinum)20228
Mobile (mobile)20229
Premium Unlimited (premium_unlimited)8000 (dedicated host once ready)

Every port serves HTTP, HTTPS, and SOCKS5 on the same host and port. Use the exact host and ports from the credentials block of each provisioning response.

List, cancel, renew, upgrade

MethodEndpointPurpose
GET/sub-accounts/{id}/subscriptionsAll subscriptions and bandwidth purchases with connection details and live usage
POST/sub-accounts/{id}/subscriptions/{sub_id}/cancelCancel a subscription (no automatic refund; contact support for refund requests)
POST/sub-accounts/{id}/subscriptions/{sub_id}/renewExtend or reactivate: body {"duration": "30_days"}
POST/sub-accounts/{id}/subscriptions/{sub_id}/upgradeMove to a higher tier mid-term

Renew applies to unlimited, ipv6, and premium_unlimited with duration of 1_day, 7_days, or 30_days. Active subscriptions extend from their current expiry; expired ones reactivate from now. The response includes previous_expiry, new_expiry, days_added, and the wholesale price charged.

Upgrade takes the field matching the product: ports (unlimited), threads (ipv6), or speed_mbps (premium_unlimited), and the new value must be higher than the current one; downgrades are rejected. The price is the prorated difference over the remaining days, and the expiry date does not change. Expired subscriptions must be renewed first.

Port configuration & country targeting (Budget Unlimited)

Budget Unlimited subscriptions expose per-port controls: each port has a rotation interval and a country setting. Defaults are rotation every 5 minutes with worldwide (all) IPs.

MethodEndpointPurpose
GET/sub-accounts/{id}/subscriptions/{sub_id}/port-configsPort range, defaults, and any per-port overrides
POST/sub-accounts/{id}/subscriptions/{sub_id}/port-configsCreate or update the config for one port
DELETE/sub-accounts/{id}/subscriptions/{sub_id}/port-configs/{config_id}Remove an override; the port reverts to defaults
POST/sub-accounts/{id}/subscriptions/{sub_id}/country-targetingSet the country for all ports at once: {"country_targeting": "US"} or "all"

The POST /port-configs body takes port_number (required, within the subscription's port range), rotation_minutes (1 to 60, default 5), country_targeting (all or an ISO-2 country code, default all), enabled (boolean), and notes (up to 255 characters). It is a strict single-port upsert: only the named port changes, never its siblings. Use the country-targeting endpoint for bulk changes.

i
What changes the IP? Changing a port's country resets that port's current IP. Changing only the rotation interval keeps the current IP and just adjusts the timer.

Proxy list generation

GET /sub-accounts/{id}/proxy-list produces ready-to-distribute proxy lines for a sub-account. The sub-account must have an active subscription or bandwidth for the requested product (403 otherwise).

ParameterValues
product_typeRequired: unlimited | ipv6 | platinum | mobile
quantity1 to 1000 (default 10)
formathost:port:username:password (default) | host:port | username:password@host:port | http://username:password@host:port | socks5://username:password@host:port | json
country, state, city, session, ttlTargeting for ipv6, platinum, and mobile lines; ttl is in minutes
curl "https://dashboard.proxyomega.com/api/reseller/v1/sub-accounts/512/proxy-list?product_type=platinum&quantity=3&format=http://username:password@host:port&country=us" \
  -H "X-API-Key: YOUR_API_KEY"

For ipv6, platinum, and mobile, if you do not pass a session, each line gets its own generated session identifier so each line holds a distinct IP. Targeting parameters are rejected with 400 for unlimited: each Budget Unlimited port already provides its own rotating IP, controlled via port configs.

Analytics

Historical usage per sub-account and across your whole book. All analytics routes require the numeric sub-account id.

MethodEndpointPurpose
GET/analytics/overviewAggregate requests, success rate, and bandwidth across all sub-accounts, with per-account rows
GET/sub-accounts/{id}/analyticsFull breakdown: summary, top target hosts, status codes, daily usage
GET/sub-accounts/{id}/analytics/summaryCompact totals for dashboards
GET/sub-accounts/{id}/analytics/usageTime series; granularity=daily (default) or hourly
GET/sub-accounts/{id}/analytics/requestsPer-request log, last 7 days; page, limit 10 to 100 (default 50)
GET/sub-accounts/{id}/analytics/portsPer-port usage: requests, success rate, and bandwidth per port

All analytics endpoints accept period: 1_day (or today), 7_days (week), 30_days (month, the default), 90_days (quarter), 365_days (year), or all.

Per-port usage

GET /sub-accounts/{id}/analytics/ports?period=30_days answers "which of this customer's ports are actually being used":

{
  "success": true,
  "data": {
    "sub_account_id": 512,
    "period": "30_days",
    "total_ports": 25,
    "total_requests": 184220,
    "total_bandwidth_gb": 42.7,
    "ports": [
      { "port": 10000, "port_type": "unlimited", "requests": 96410, "successful": 95514, "success_rate": 99.1, "bandwidth_gb": 21.9 },
      { "port": 10001, "port_type": "unlimited", "requests": 87810, "successful": 86733, "success_rate": 98.8, "bandwidth_gb": 20.8 }
    ]
  }
}

Live connections

Real-time and recent-history concurrency monitoring, useful for spotting sub-accounts near their connection limits. Numeric sub-account ids only. Figures can lag by up to about 30 seconds.

MethodEndpointPurpose
GET/connections/overviewLive utilization across all sub-accounts; window_minutes 1 to 15 (default 5)
GET/sub-accounts/{id}/connectionsActive connections vs. limit, plus per-port requests/sec and Mbps in/out
GET/sub-accounts/{id}/connections/historyConnection history with peak usage

The overview labels each sub-account idle, active, moderate, or near_limit and flags near_limit_accounts so you can act before customers hit their ceiling. History accepts period (1_hour, 6_hours, 24_hours default, 7_days, 30_days) and granularity (auto default, 5_min, 15_min, 1_hour, 6_hours, 1_day; the finest granularities are available for recent windows only) and includes a peak block with the highest concurrency and when it happened.

Errors

Errors use the standard envelope ("success": false plus an error string) with conventional HTTP status codes:

StatusMeaning
400Validation error, unsupported value, or insufficient balance (includes required vs. available amounts)
401Missing or invalid API key, KYC verification required, or account suspended
403Action requires verified KYC, or no active subscription for the requested product
404Resource not found
405Method not allowed on this endpoint
409Conflict: duplicate username, IP already whitelisted, or a port tier temporarily unavailable
410The sub-account has been deleted
429Rate limit exceeded; check the X-RateLimit-* headers
500 / 503Server error or a dependency temporarily unavailable; retry with backoff
{
  "success": false,
  "error": "Insufficient balance. Required: $100.00, Available: $25.00"
}

Test sandbox

A full mock of the API is available for integration testing, no authentication required:

https://dashboard.proxyomega.com/api/reseller/v1/dev

The sandbox mirrors the production paths and response envelopes, returns mock data, and marks every response with "_dev_mode": true. Nothing is created and nothing is charged. Mock error scenarios are supported so you can exercise your error handling.

i
Sandbox prices are not real. The mock data does not reflect current pricing. Always take live prices from the production GET /products endpoint.

How to become a reseller

i
Apply and verify in the dashboard. Sign in at dashboard.proxyomega.com, apply for a reseller account, and complete KYC verification. Once approved and verified, the Reseller API is enabled with your account API key. Read more at proxyomega.com/reseller-program, or email [email protected] with questions about reseller access.
  • Public API. Self-service API for managing your own account.
  • Authentication. The three ways to authenticate proxy connections.
  • Targeting. Country, state, city, ASN, session, and TTL parameters.
  • Sessions & rotation. How sticky sessions and rotation behave per product.

Last updated July 10, 2026