Proxy plans now up to 15% cheaper
View pricing

Reseller API

Use the Reseller API to order, provision, and manage proxy services programmatically. Authentication, endpoints, and request examples.

API reference25 min readLast updated September 2026

The Reseller API is the proxy reseller API for ordering, provisioning, and managing ColdProxy services at scale. It is the wholesale provisioning interface for partners who buy ColdProxy plans in volume and resell them to their own customers, with every order paid from a prepaid reseller credit balance. Use it to order new services, run the full lifecycle, and track your balance over a single JSON HTTP endpoint. It is the B2B layer above the per-service Customer Plan API: the Reseller API manages services as billable units (order, suspend, renew), while the per-service API manages the proxies inside a single plan.

Reseller API overview

The Reseller API lets you run your entire ColdProxy supply chain over a single JSON HTTP endpoint. With it you can:

  • Look up the products, pricing, and configuration options available to your reseller account.
  • Order and provision new proxy services in real time.
  • Manage the full service lifecycle: suspend, unsuspend, change passwords, upgrade, renew, and terminate.
  • Track your orders and your prepaid reseller credit balance.

Who it is for. This API is built for resellers and platform partners who provision ColdProxy services on behalf of their own customers: for example, a proxy marketplace, a SaaS product that bundles proxies, or an agency that manages many client subscriptions. If you only need to manage a single plan you already purchased, use the Customer Plan API in that plan's settings instead. For program context, see /blog/proxy-reseller-program-infrastructure/. Not a reseller yet? Apply through the ColdProxy reseller program.

How billing works. Every provisioning and renewal action is charged against your prepaid reseller credit balance. Invoices are settled automatically from that balance; you never pay one manually. As long as your balance covers the order, the action completes immediately. You top up your balance in the reseller portal and check it any time with GetCredits.

Base endpoint

All requests are a single POST to:

Shell
POST https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/

Send a JSON body, set Content-Type: application/json, and choose the operation with the action field. There is one endpoint for every action; you never change the URL.

Authentication

Every request is authenticated with two values tied to your reseller account:

Authentication
Credential What it is
username The reseller account email address.
api_key A secret key generated in your reseller portal. Typically 32 characters (configurable 16–64).

Sign in to the ColdProxy reseller portal and open your API settings to generate the api_key. Treat it like a password: it grants full programmatic control of your reseller account and your prepaid balance.

Danger

Never commit your api_key to source control, embed it in client-side code, or share it. If a key is exposed, regenerate it in the portal and update your integrations immediately.

You can supply your credentials in any one of three equivalent ways. Pick whichever fits your HTTP client, and use one method per request for clarity.

Method 1 — JSON body fields

Include username and api_key directly in the request body alongside the action.

Shell
curl -X POST "https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "TestConnection",
    "username": "you@example.com",
    "api_key": "YOUR_32_CHAR_OR_LONGER_API_KEY"
  }'

Method 2 — X-API-* headers

Send the credentials as request headers and keep the body to just the action and its parameters.

Shell
curl -X POST "https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/" \
  -H "Content-Type: application/json" \
  -H "X-API-Username: you@example.com" \
  -H "X-API-Key: YOUR_32_CHAR_OR_LONGER_API_KEY" \
  -d '{ "action": "TestConnection" }'

Method 3 — HTTP Basic auth

Pass username:api_key as standard HTTP Basic credentials. Most HTTP libraries handle the Base64 encoding for you.

Shell
curl -X POST "https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/" \
  -H "Content-Type: application/json" \
  -u "you@example.com:YOUR_32_CHAR_OR_LONGER_API_KEY" \
  -d '{ "action": "TestConnection" }'

All three are equivalent. The examples in the rest of this reference put credentials in the JSON body for readability, but you can switch to headers or Basic auth at any time.

Request and response conventions

Requests. Every request is an HTTP POST with a JSON body and Content-Type: application/json. The action field selects the operation; all other fields are the parameters for that action.

JSON
{
  "action": "ActionName",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "param_one": "value",
  "param_two": "value"
}

Responses. Every response is JSON and follows one envelope. A successful call returns result: "success" plus the action-specific data:

JSON
{
  "result": "success"
}

A failed call returns result: "error", a human-readable message, and a stable machine-readable code you can branch on:

JSON
{
  "result": "error",
  "message": "A human-readable explanation of what went wrong.",
  "code": "ERROR_CODE"
}
Tip

Always branch on the code field, not the message. Messages are written for humans and may be reworded over time; code values are stable. For the HTTP-level meaning of 429 and similar codes, see /blog/proxy-error-codes-407-403-429-502-and-504-explained/.

Standard error codes

Standard error codes
Code HTTP Meaning
AUTH_REQUIRED 401 The request did not include credentials.
INVALID_CREDENTIALS 401 The username or api_key is wrong.
API_DISABLED 403 API access is disabled for your reseller account.
GROUP_API_DISABLED 403 API access is disabled for your reseller group.
IP_NOT_ALLOWED 403 The request came from an IP that is not on your account's IP allow-list.
MISSING_ACTION 400 No action field was sent.
INVALID_ACTION 400 The action value is not a recognized action (the match is case-sensitive).
MISSING_PARAMETERS 400 A required parameter for the action is missing.
PERMISSION_DENIED 403 The action is not enabled for your reseller group (see Permissions).
PRODUCT_NOT_AVAILABLE 400 The requested product is not in your reseller catalog (Create, Upgrade).
PRODUCT_NOT_ALLOWED 403 The action is not permitted on this service's product. Applies only to services that were not created through this API.
SERVICE_NOT_FOUND 404 The service_id does not exist or does not belong to your account. One rare renewal-path lookup failure returns this code with HTTP 400.
INVALID_STATUS 400 The service is not in a status that allows this action.
REQUIRED_CONFIG_OPTIONS_MISSING 400 A Create request is missing one or more required product configuration options in options{}.
INVALID_OPTIONS 400 The options{} payload is malformed (for example, not an object).
INVALID_CONFIG_OPTION_VALUES 400 One or more values in options{} are not valid for the product.
CUSTOM_FIELDS_VALIDATION_FAILED 400 One or more values in custom_fields{} failed validation (for example, a required custom field is missing or empty).
INVALID_CUSTOM_FIELDS 400 The custom_fields{} payload is malformed (not an object) or names a field the product does not have.
PAYMENT_REQUIRED 402 Your balance could not cover a Create or Upgrade. The order is cancelled automatically and nothing is charged — top up and retry.
INSUFFICIENT_CREDITS 400 Your balance could not cover a Renew. The renewal invoice stays open, and your next Renew call pays that same invoice.
REQUEST_IN_PROGRESS 409 Another request for the same account, service, or idempotency_key is still being processed. Retry after a short wait.
IDEMPOTENCY_KEY_CONFLICT 409 The same idempotency_key was reused with a different payload.
RATE_LIMIT_EXCEEDED 429 You have exceeded your request rate limit.
PAYLOAD_TOO_LARGE 413 The JSON request body is larger than 1MB.
SYSTEM_ERROR 500 Something failed on our side. Retry later or contact support.
Note

The response field shapes shown throughout this reference are illustrative: they show the keys you can rely on plus representative values. Optional or environment-specific fields may also be present; treat unknown fields as additive and forward-compatible.

Actions reference

There are 15 actions, grouped by purpose:

Actions reference
Action Group What it does
TestConnection Connection & account Verify your credentials and connectivity.
GetCredits Connection & account Your prepaid credit balance and credit history.
GetProducts Connection & account List resellable products with pricing and options.
GetCustomFields Connection & account Custom fields a product defines and what they accept.
TestCreate Provisioning Validate a Create payload with no charge and no provisioning.
Create Provisioning Order and pay for a new service from your credit balance.
GetServiceInfo Provisioning Service details, real proxy credentials, per-service API access.
GetOrders Provisioning Paginated list of your services, with optional filters.
SetServiceNote Provisioning Attach or update an internal note on a service.
Suspend Lifecycle Suspend an active service.
Unsuspend Lifecycle Reactivate a suspended service.
ChangePassword Lifecycle Set a new proxy-authentication password.
Renew Lifecycle Renew one billing period from your credit balance.
Upgrade Lifecycle Move a service to a different product or billing cycle. Disabled by default.
Terminate Lifecycle Permanently end a service, immediately and irreversibly. Disabled by default.

Each action below lists its purpose, parameters, a copy-paste request, and a representative success response.

Connection & account

TestConnection

Purpose: Verify that your credentials and connectivity are working. Use it as a health check before running real provisioning logic.

Parameters: none beyond authentication.

JSON
{
  "action": "TestConnection",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "API connection successful",
  "version": "1.8.15",
  "timestamp": "2026-06-02 12:00:00"
}
Note

You can also call TestConnection with no credentials at all, as a plain availability ping. That variant replies with "message": "API is online" and a numeric Unix timestamp.

GetCredits

Purpose: Return your current prepaid reseller credit balance and a paginated history of credit movements. Check this before bulk provisioning so you do not run out of balance mid-batch.

GetCredits
Parameter Required Description
page optional Page number for the credit history.
limit optional Items per page (default 20, max 100).
JSON
{
  "action": "GetCredits",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "page": 1
}

Success response (illustrative):

JSON
{
  "result": "success",
  "credits": {
    "balance": 250.0,
    "currency": { "code": "USD", "prefix": "$", "suffix": "" },
    "formatted": "$250.00"
  },
  "transactions": [
    {
      "id": 1235,
      "date": "2026-06-01 10:00:00",
      "description": "Invoice paid from credit",
      "amount": -12.0
    },
    {
      "id": 1234,
      "date": "2026-05-30 09:00:00",
      "description": "Balance top-up",
      "amount": 100.0
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 2, "total_pages": 1, "has_more": false }
}

Your balance and currency live inside the credits object. Transaction amounts are signed numbers (spending shows as negative entries) and the list is sorted newest first.

GetProducts

Purpose: List the products available to your reseller account, with their pricing, configuration options, and custom fields. This is the source of truth for building a valid Create request; read it first so you know which options{} and custom_fields{} a product requires. Pass an optional product_id to scope the response to a single product.

GetProducts
Parameter Required Description
product_id optional Return only this product instead of the full catalog.
JSON
{
  "action": "GetProducts",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "products": [
    {
      "id": 101,
      "name": "Premium Residential Geo Target IPv4 (Unmetered)",
      "description": "Speed-tier residential plan with geo targeting.",
      "domain_required": false,
      "pricing": {
        "monthly": {
          "label": "Monthly",
          "base_price": 45.0,
          "min_config_price": 0.0,
          "total_price": 45.0,
          "setup": 0.0
        }
      },
      "options": [
        {
          "name": "Speed",
          "key": "speed",
          "type": "dropdown",
          "values": [
            { "value": "25 Mbps", "label": "25 Mbps", "pricing": { "monthly": 0.0 } },
            { "value": "50 Mbps", "label": "50 Mbps", "pricing": { "monthly": 25.0 } }
          ]
        }
      ],
      "custom_fields": []
    }
  ],
  "total": 1,
  "currency": { "code": "USD", "prefix": "$", "suffix": "" }
}

The billing cycles a product supports are the keys of its pricing object; read them from there instead of hardcoding a list. Every visible dropdown or radio option in options must be sent in your Create request, using the option's key.

Note

When a promotion applies to your account, the pricing cycles the promotion covers also include original_price and discount (with total_price already discounted), and each option value's pricing entry becomes an object ({"price": ..., "original_price": ..., "discount": ...}) instead of a plain number. Build your parser to accept both shapes. If no products are assigned to your account yet, the response is "products": [] with a message, and the total and currency keys are absent.

The four ColdProxy proxy products you can resell:

  • Premium Residential Geo Target IPv4 (Unmetered) — speed-tier (Mbps) residential plan, 195+ countries, sticky sessions from 5s to 24h. Billed hourly, daily, weekly, or monthly.
  • Premium Residential Geo Target IPv4 (GB Based) — monthly traffic packs, 195+ countries, sticky sessions from 5s to 24h. Monthly billing only.
  • Residential IPv6 — speed-tier (Mbps) USA plan that includes a /32 subnet, sticky sessions from 5s to FOREVER. Billed hourly, daily, weekly, or monthly.
  • Datacenter IPv6 — speed-tier (Mbps) plan across 25 supported countries and 47 locations (plus an "All Country" random option), a private /48 per location, sticky sessions from 5s to FOREVER, and CDN-aware IPv6 reachability for supported CDN-fronted domains. Billed daily, weekly, or monthly.
Note

Always read live values from GetProducts rather than hardcoding prices or option lists. Pricing, available speed tiers, and configuration options can change, and your reseller account may see a tailored catalog. The product_id values (101/102) in these examples are placeholders; use the IDs returned by GetProducts. See /pricing/ for the public lineup.

GetCustomFields

Purpose: Return the custom fields defined for a specific product, including which are required and what values they accept. Use it to build the custom_fields{} object for Create when a product needs more than configuration options.

GetCustomFields
Parameter Required Description
product_id required The product whose custom fields you want.
JSON
{
  "action": "GetCustomFields",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "product_id": 101
}

Success response (illustrative):

JSON
{
  "result": "success",
  "product_id": 101,
  "product_name": "Premium Residential Geo Target IPv4 (Unmetered)",
  "custom_fields": [
    {
      "name": "Label",
      "type": "text",
      "required": false,
      "description": "A label for your own reference.",
      "options": [],
      "regexpr": ""
    }
  ],
  "total": 1
}

regexpr is the validation pattern a field value must match in Create (an empty string means no pattern). Use the field's name as the key in your custom_fields{} object.

Provisioning

TestCreate — the safe dry-run

Purpose: Validate a Create request without charging your balance or provisioning anything. TestCreate runs the same validation as Create (config options, custom fields, domain requirement) and returns a simulated result that mirrors a real Create response: status and provisioned echo what a successful order would return. The test: true flag, the _test_info block, and the "No charges applied" message confirm nothing was actually created. It is exempt from rate limiting, so you can call it freely while building and testing your integration.

Always run TestCreate first when you add support for a new product or change your Create payload.

Parameters: identical to Create (see below), except idempotency_key, which TestCreate ignores.

JSON
{
  "action": "TestCreate",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "product_id": 101,
  "billing_cycle": "monthly",
  "options": { "Speed": "25 Mbps" },
  "custom_fields": {}
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "Test order validated successfully. No charges applied.",
  "test": true,
  "order_id": 612345,
  "invoice_id": 612346,
  "service_id": 612347,
  "product_id": 101,
  "billing_cycle": "monthly",
  "amount_paid": 45.0,
  "status": "Active",
  "provisioned": true,
  "created_date": "2026-06-02",
  "next_due_date": "2026-07-02",
  "username": "test_user_1a2b3c4d",
  "password": "***",
  "_test_info": {
    "validation_passed": true,
    "sufficient_credits": true,
    "current_balance": 250.0,
    "would_charge": 45.0,
    "options_validated": 1,
    "custom_fields_validated": 0
  }
}
Note

would_charge is an estimate: the product's base price plus setup fee, after any discount. It does not include configurable-option pricing, so the real Create charge can be higher on products with priced options. The test: true flag also appears on TestCreate error responses.

Create

Purpose: Order and pay for a new service in one call, from your prepaid reseller credit balance. On success the order is placed and paid; check status and provisioned in the response, because the service may still be Pending while provisioning completes.

Create
Parameter Required Description
product_id required The product to order (from GetProducts).
billing_cycle required A billing cycle the product supports. Read the exact cycle keys from the product's pricing object in GetProducts (for example monthly).
options required if the product has config options Object of configuration option values.
custom_fields required if the product has required custom fields Object of custom field values.
domain only if the product requires it Domain value for products that need one.
idempotency_key optional Safe-retry key — see Idempotency & rate limiting.

Create validation rules:

  • options{} — every visible dropdown/radio configuration option for the product is required. Missing options return REQUIRED_CONFIG_OPTIONS_MISSING; invalid values return INVALID_CONFIG_OPTION_VALUES; a malformed options{} payload (not an object) returns INVALID_OPTIONS.
  • custom_fields{} — every required custom field must pass validation. Missing or invalid values return CUSTOM_FIELDS_VALIDATION_FAILED; a malformed payload or an unknown field name returns INVALID_CUSTOM_FIELDS.
  • domain — only include it when the product requires a domain. Omit it otherwise.

Use GetProducts and GetCustomFields to discover exactly which options and fields a product needs, and validate with TestCreate before going live.

JSON
{
  "action": "Create",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "product_id": 101,
  "billing_cycle": "monthly",
  "options": { "Speed": "25 Mbps" },
  "custom_fields": {},
  "idempotency_key": "order-2026-06-02-abc123"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "Order created successfully",
  "order_id": 50231,
  "invoice_id": 90230,
  "service_id": 80417,
  "product_id": 101,
  "billing_cycle": "monthly",
  "amount_paid": 45.0,
  "status": "Pending",
  "provisioned": false,
  "created_date": "2026-06-02",
  "username": "user80417",
  "password": "***"
}

A paid order with "status": "Pending" and "provisioned": false is a normal result; provisioning finishes shortly after. Poll GetServiceInfo until the service is Active. The password field is always masked as ***; read the real credentials from GetServiceInfo. next_due_date, domain, username, and password appear only when they have values.

Note

If your balance cannot cover the order, you get HTTP 402 with code PAYMENT_REQUIRED. The just-created order is cancelled automatically and nothing is charged; top up your balance and retry safely.

Note

Residential IPv4 (GB Based) and Residential IPv6 activate instantly after payment clears. Residential IPv4 (Unmetered) and Datacenter IPv6 start automatic setup after payment clears; allow up to 10 minutes and connect as soon as setup completes. See Activation and setup times. Manage the proxies inside a service (proxy lists, authorized IPs, geo targeting) with the per-service Customer Plan API, not this endpoint.

GetServiceInfo

Purpose: Return the current details and status of a service on your reseller account, including the service's real proxy credentials and, for proxy services, the per-service API access details.

GetServiceInfo
Parameter Required Description
service_id required The service to look up.
JSON
{
  "action": "GetServiceInfo",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417
}

Success response (illustrative):

JSON
{
  "result": "success",
  "service": {
    "id": 80417,
    "order_id": 50231,
    "product_id": 101,
    "product_name": "Premium Residential Geo Target IPv4 (Unmetered)",
    "username": "user80417",
    "password": "pr0xy-Example-Pass",
    "status": "Active",
    "billing_cycle": "Monthly",
    "price": 45.0,
    "registration_date": "2026-06-02",
    "next_due_date": "2026-07-02",
    "suspend_reason": null,
    "reseller_api": true,
    "client_note": null
  },
  "options": [
    { "key": "speed", "name": "Speed", "value": "25 Mbps" }
  ],
  "custom_fields": {},
  "api": {
    "endpoint": "https://members.coldproxy.com/newsysapi.php",
    "key": "EXAMPLE-SERVICE-KEY-DO-NOT-USE",
    "service_url": "https://members.coldproxy.com/clientarea.php?action=productdetails&id=80417",
    "description": "To find all available APIs to control your plan, check the service page at: https://members.coldproxy.com/clientarea.php?action=productdetails&id=80417"
  }
}

The service details are nested under service, with options, custom_fields, and api as siblings. This is where you read the real username and password after Create. Status values are capitalized (Active, Pending, Suspended, Terminated), and billing_cycle is a display label. The keys domain, dedicated_ip, assigned_ips, and expiry_timestamp appear only when they have values.

The api object is the gateway to per-service proxy management; see Managing the proxies inside a service. It is null when per-service credentials are not available (for example, right after Create while provisioning is still running).

GetOrders

Purpose: Return a paginated list of the services on your reseller account, with optional filters. Each item represents one service; order_id links it to its order when one exists.

GetOrders
Parameter Required Description
status optional Filter by service status. Matching is case-insensitive (e.g. active, suspended, terminated).
product_id optional Filter by product.
include_all_services optional Default false returns only services created through this API. Set true to also list every other service on your account (those have "created_via_api": false).
page optional Page number.
limit optional Items per page (default 50, max 100).
JSON
{
  "action": "GetOrders",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "status": "active",
  "page": 1
}

Success response (illustrative):

JSON
{
  "result": "success",
  "orders": [
    {
      "order_id": 50231,
      "service_id": 80417,
      "product_id": 101,
      "product_name": "Premium Residential Geo Target IPv4 (Unmetered)",
      "domain": "",
      "status": "Active",
      "billing_cycle": "Monthly",
      "amount": 45.0,
      "registration_date": "2026-06-02",
      "next_due_date": "2026-07-02",
      "terminated_on": null,
      "created_at": "2026-06-02 12:00:00",
      "created_via_api": true
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 1, "total_pages": 1, "has_more": false }
}

amount is the service's current renewal price, not the amount you originally paid for the order. order_id can be null for services that have no order. Returned status values are capitalized.

SetServiceNote

Purpose: Attach or update a short internal note on a service you provisioned (for example, your own customer reference). The note is stored on the service in the members portal.

SetServiceNote
Parameter Required Description
service_id required The service to annotate.
note optional The note text — max 200 characters, HTML is removed automatically. Omit it or send an empty value to clear the note.
JSON
{
  "action": "SetServiceNote",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417,
  "note": "Customer: Acme Corp — renewed 2026-06"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "service_id": 80417,
  "client_note": "Customer: Acme Corp — renewed 2026-06",
  "action": "saved"
}

Lifecycle

Suspend

Purpose: Suspend an active service (for example, when your customer's subscription lapses). An optional reason is stored with the suspension.

Suspend
Parameter Required Description
service_id required The service to suspend.
reason optional A short reason recorded with the suspension (up to 255 characters). A standard note is used when omitted.
JSON
{
  "action": "Suspend",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417,
  "reason": "Customer subscription unpaid"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "service_id": 80417,
  "status": "Suspended",
  "suspend_reason": "Customer subscription unpaid",
  "suspended_date": "2026-06-10 14:02:11"
}

Unsuspend

Purpose: Reactivate a suspended service.

Unsuspend
Parameter Required Description
service_id required The service to reactivate.
JSON
{
  "action": "Unsuspend",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417
}

Success response (illustrative):

JSON
{
  "result": "success",
  "service_id": 80417,
  "status": "Active",
  "unsuspended_date": "2026-06-10 15:20:43"
}
Note

Only services suspended through this API can be unsuspended; lifting a suspension made by ColdProxy staff or billing returns UNSUSPEND_NOT_ALLOWED. A service with an overdue renewal invoice returns OVERDUE_INVOICES; renew it first, then unsuspend.

ChangePassword

Purpose: Set a new password for a service's proxy authentication.

ChangePassword
Parameter Required Description
service_id required The service whose password to change.
password required The new password to set — 6 to 128 characters (the minimum is configurable, 6 by default; too short or too long returns INVALID_PASSWORD).
JSON
{
  "action": "ChangePassword",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417,
  "password": "new-strong-password"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "Password changed successfully",
  "service_id": 80417,
  "changed_date": "2026-06-10 14:02:11"
}

Works on Active or Suspended services; other statuses return INVALID_STATUS.

Tip

Changing the password invalidates any user:pass proxy strings already issued for that service. Re-pull the service's proxy list afterward so your customer's workers keep authenticating.

Renew

Purpose: Renew a service for one billing period, charged to your prepaid reseller credit balance; for a monthly service this advances the next due date by one month. There is no multi-period parameter; call Renew once per period. Works on Active or Suspended services.

Renew
Parameter Required Description
service_id required The service to renew.
idempotency_key optional Safe-retry key — see Idempotency & rate limiting.
JSON
{
  "action": "Renew",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417,
  "idempotency_key": "renew-80417-2026-06"
}

Success response (illustrative): renewing a monthly service whose next_due_date was 2026-07-02 advances it by one month to 2026-08-02:

JSON
{
  "result": "success",
  "service_id": 80417,
  "invoice_id": 90231,
  "amount_paid": 45.0,
  "billing_cycle": "Monthly",
  "next_due_date": "2026-08-02"
}

billing_cycle in the Renew response is a display label (for example Monthly), not the lowercase cycle key you send to Create. next_due_date appears when the service has a known due date.

Note

If your balance cannot cover the renewal, you get HTTP 400 with code INSUFFICIENT_CREDITS. The renewal invoice stays open; your next Renew call for that service pays the same invoice, so retrying never creates duplicate invoices or charges.

Upgrade

Purpose: Move a service to a different product (or a different billing cycle) without terminating it. The price difference is calculated for you: an upgrade is charged to your prepaid reseller credit balance, and a downgrade is returned to that balance as credit.

Upgrade
Parameter Required Description
service_id required The service to change. The service must be Active.
new_product_id required The target product (from GetProducts).
billing_cycle optional Billing cycle for the new product. Defaults to the service's current cycle; it must be available on the target product.
idempotency_key optional Safe-retry key — see Idempotency & rate limiting.
JSON
{
  "action": "Upgrade",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417,
  "new_product_id": 102,
  "billing_cycle": "monthly",
  "idempotency_key": "upgrade-80417-2026-06"
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "Service upgraded successfully",
  "service_id": 80417,
  "upgrade_order_id": 50298,
  "invoice_id": 90312,
  "old_product_id": 101,
  "old_product_name": "Premium Residential Geo Target IPv4 (Unmetered)",
  "new_product_id": 102,
  "new_product_name": "Premium Residential Geo Target IPv4 (GB Based)",
  "billing_cycle": "monthly",
  "status": "Active",
  "type": "upgrade",
  "amount_paid": 12.5
}

type tells you which way the change went. On an "upgrade" you pay amount_paid from credit. On a "downgrade" the response carries refund_amount instead, and that amount is returned to your credit balance. Requesting the product and cycle the service already has is a no-op: you get success with already_applied: true and no charge.

Note

If your balance cannot cover the upgrade, you get HTTP 402 with code PAYMENT_REQUIRED. The upgrade is rolled back and nothing is charged; top up and retry safely.

Warning

Upgrade and Terminate are disabled for reseller accounts by default. If you receive PERMISSION_DENIED, ask your ColdProxy account manager to enable them for your group.

Terminate

Purpose: Permanently end a service. Termination is immediate (the proxies stop working as soon as the call succeeds) and the service cannot be brought back through this API.

Terminate
Parameter Required Description
service_id required The service to terminate.
JSON
{
  "action": "Terminate",
  "username": "you@example.com",
  "api_key": "YOUR_API_KEY",
  "service_id": 80417
}

Success response (illustrative):

JSON
{
  "result": "success",
  "message": "Service terminated successfully",
  "service_id": 80417,
  "status": "Terminated",
  "terminated_date": "2026-06-10 14:02:11"
}

Any service that is not already terminated or cancelled can be terminated, including suspended ones. Calling it again returns ALREADY_TERMINATED.

Warning

Terminate is permanent. If you only need to pause a service (for example while your customer settles a bill), use Suspend instead; that is reversible with Unsuspend. Like Upgrade, this action is disabled by default (see the note above).

Managing the proxies inside a service

The Reseller API manages services as billable units: you order, renew, suspend, and terminate them. Everything that happens inside a service (generating proxy lists, the IP allow-list, geo targeting, usage, bandwidth top-ups, password rotation) belongs to the per-service Customer Plan API.

You do not need the client area to use it. For every proxy service you provision, GetServiceInfo returns that service's API endpoint and key in its api field:

JSON
"api": {
  "endpoint": "https://members.coldproxy.com/newsysapi.php",
  "key": "EXAMPLE-SERVICE-KEY-DO-NOT-USE",
  "service_url": "https://members.coldproxy.com/clientarea.php?action=productdetails&id=80417",
  "description": "To find all available APIs to control your plan, check the service page at: https://members.coldproxy.com/clientarea.php?action=productdetails&id=80417"
}

Call the Customer Plan API with the service ID and that key:

Code
GET https://members.coldproxy.com/newsysapi.php?id=80417&key=EXAMPLE-SERVICE-KEY-DO-NOT-USE&a=info

A complete integration uses the two APIs together:

  1. Order a service with Create (Reseller API).
  2. Read api.endpoint and api.key from GetServiceInfo (Reseller API).
  3. Operate the proxies (generate lists, authorize IPs, watch usage) with the Customer Plan API.
  4. Bill — Renew, Suspend, Unsuspend, or Terminate as your customer's subscription changes (Reseller API).

For white-label delivery, pass hostname=no to the Customer Plan API proxies action, or turn off the client area's Use Hostname instead of IP option, to deliver proxy lists as IP:port instead of the gateway hostname.

Note

api is null when the per-service credentials are not available yet: most commonly right after Create, before provisioning finishes. Wait for the service to become Active and call GetServiceInfo again. Treat api.key like a password: it grants full control of that service's proxies.

Permissions

Available actions and products are controlled per reseller group. Your account inherits its permissions from the group an administrator assigns it to. Most actions in this reference are enabled for reseller accounts by default; two are not: Upgrade and Terminate ship disabled and must be switched on for your group. Ask your ColdProxy account manager if you need them.

If you call an action your group is not permitted to use, you receive PERMISSION_DENIED (your credentials are valid, but the action is not enabled for your group). An unrecognized action value returns INVALID_ACTION. Product access works separately: ordering a product that is not in your catalog returns PRODUCT_NOT_AVAILABLE, and managing an existing service whose product does not permit that action returns PRODUCT_NOT_ALLOWED (this applies only to services that were not created through this API).

To add products to your catalog or request additional permissions for your group, contact your ColdProxy account manager.

Idempotency & rate limiting

Idempotency

Create, Upgrade, and Renew are charging actions. To make them safe to retry after a timeout or network blip without double-charging, send an optional idempotency_key: any unique string you generate per logical operation (for example, your own order reference; up to 191 characters).

  • If the original request succeeded, retrying with the same key returns the saved response instead of running the operation again. No second charge.
  • If the original request failed, the key is released; retrying with the same key runs the operation fresh.
  • If a request with that key is still being processed when a duplicate arrives, the duplicate returns HTTP 409 with code REQUEST_IN_PROGRESS. Wait briefly and retry.
  • If you reuse a key with a different payload, you get HTTP 409 with code IDEMPOTENCY_KEY_CONFLICT.

Use a fresh idempotency_key for each distinct operation, and reuse the same key only when retrying that exact operation.

Rate limiting

Requests can be rate-limited per reseller account; your administrator enables and sizes the limit. When you exceed it, the API returns HTTP 429 with code RATE_LIMIT_EXCEEDED, a retry_after field in the body, and these headers:

Rate limiting
Header Meaning
Retry-After Seconds to wait before retrying.
X-RateLimit-Limit Your request allowance for the window.
X-RateLimit-Remaining Requests remaining in the current window.
X-RateLimit-Reset Unix timestamp when the current window resets.

Successful responses also carry the X-RateLimit-Limit and X-RateLimit-Remaining headers (X-RateLimit-Remaining is -1 when no limit is active). Respect Retry-After and use exponential backoff for resilient automation.

Tip

TestCreate is exempt from rate limiting. You can validate Create payloads as often as you need while building and testing, without consuming your rate budget.

Quickstart

This quickstart authenticates, lists your available products, then dry-runs a Create with TestCreate, all without charging your balance or provisioning anything.

cURL

Shell
BASE="https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/"
USER="you@example.com"
KEY="YOUR_32_CHAR_OR_LONGER_API_KEY"

# 1. Verify credentials and connectivity
curl -X POST "$BASE" \
  -H "Content-Type: application/json" \
  -d "{\"action\":\"TestConnection\",\"username\":\"$USER\",\"api_key\":\"$KEY\"}"

# 2. List the products you can resell
curl -X POST "$BASE" \
  -H "Content-Type: application/json" \
  -d "{\"action\":\"GetProducts\",\"username\":\"$USER\",\"api_key\":\"$KEY\"}"

# 3. Dry-run an order (no charge, no provisioning)
curl -X POST "$BASE" \
  -H "Content-Type: application/json" \
  -d "{
    \"action\":\"TestCreate\",
    \"username\":\"$USER\",
    \"api_key\":\"$KEY\",
    \"product_id\":101,
    \"billing_cycle\":\"monthly\",
    \"options\":{\"Speed\":\"25 Mbps\"},
    \"custom_fields\":{}
  }"

Python

Python
import requests

BASE = "https://members.coldproxy.com/modules/addons/coldproxy_product_reseller/api/"
AUTH = {
    "username": "you@example.com",
    "api_key": "YOUR_32_CHAR_OR_LONGER_API_KEY",
}


def call(action, **params):
    payload = {"action": action, **AUTH, **params}
    resp = requests.post(BASE, json=payload, timeout=30)
    data = resp.json()
    if data.get("result") != "success":
        raise RuntimeError(f"{data.get('code')}: {data.get('message')}")
    return data


# 1. Verify credentials and connectivity
print(call("TestConnection"))

# 2. List the products you can resell
products = call("GetProducts")["products"]
for p in products:
    print(p["id"], p["name"], list(p["pricing"].keys()))

# 3. Dry-run an order (no charge, no provisioning)
dry_run = call(
    "TestCreate",
    product_id=101,
    billing_cycle="monthly",
    options={"Speed": "25 Mbps"},
    custom_fields={},
)
print("Test mode:", dry_run.get("test"))
print("Estimated charge:", dry_run.get("amount_paid"))

Once TestConnection succeeds, GetProducts shows your real catalog, and TestCreate returns test: true with provisioned: true, switch the TestCreate call to Create (and add an idempotency_key) to provision a live service. Watch your prepaid reseller credit balance with GetCredits so bulk runs never stall mid-batch, and manage the proxies inside each service with the Customer Plan API. For broader integration patterns, see /blog/proxy-automation-api-integration-guide/.

Need a tailored proxy plan for a large project?

Need a different speed or traffic allowance? Contact us through the channels on our website so we can assess whether a custom plan is possible.

Contact Our Sales TeamTelegram & ticket support · English and Arabic