Skip to content

Reseller API

Programmatic access for approved resellers: browse your product catalog, place balance-paid orders, retrieve proxy credentials, and monitor traffic usage — all over a simple REST API.

Copies the full API docs (Markdown) to your clipboard — paste into ChatGPT / Claude to help you integrate

API at a glance

  • Base URL: https://hellworld.io/openapi/v1
  • Auth: Authorization: Bearer <key_id>.<key_secret>
  • Format: JSON over HTTPS
  • Billing: prepaid account balance (USD)
  • Rate limit: per reseller — 300 requests/min (reads), 60/min (writes / order creation). Up to 5 active keys per reseller.

Overview

The Reseller API is available to approved reseller accounts. Your account manager enables specific products for your account and configures your reseller pricing. Only products enabled for your account appear in the API.

The typical integration loop:

  1. GET /products — see your enabled products and unit prices
  2. POST /orders — place an order, paid from your prepaid balance
  3. GET /orders/{order_ref} — confirm order state
  4. GET /proxies — retrieve proxy credentials and live traffic usage
  5. Build proxy strings using the per-product gateway formats below

Currently available products (first batch):

product_codeProductCategoryBilling
MOBILE-ETET Mobilemobileper GB
RES-GEOFASTGeofastresidentialper GB

More products can be enabled for your account on request.

Authentication

Create an API key in your Reseller Portal (Dashboard → Reseller Portal → API Keys). A key has two parts:

  • Key ID — starts with dk_live_, safe to log
  • Key Secret — shown only once at creation; store it securely

Send both on every request, joined by a dot:

Authorization: Bearer dk_live_AbCdEf1234567890.YOUR_KEY_SECRET
bash
curl -s https://hellworld.io/openapi/v1/products \
  -H "Authorization: Bearer dk_live_AbCdEf1234567890.YOUR_KEY_SECRET"

Common pitfalls

  • The header value is Bearer + one space + key_id.key_secret — the first dot separates ID from secret.
  • Write requests also require Content-Type: application/json and an Idempotency-Key header (see Idempotency).
  • Rate limits are per reseller (shared across all your keys): 300 requests/min for reads, 60/min for writes (order creation). On 429 RATE_LIMITED, honor the Retry-After response header. You may hold up to 5 active API keys.
  • Keys can be revoked and re-created in the portal at any time. Revocation is immediate.

Authentication errors:

HTTPcodeMeaning
401AUTH_MISSING_KEYNo Authorization header
401AUTH_INVALID_KEYMalformed key, unknown key ID, or secret mismatch
401AUTH_KEY_REVOKEDKey was revoked in the portal
401AUTH_KEY_EXPIREDKey past its expiry date
403DEALER_SUSPENDEDReseller account disabled — contact your account manager
429RATE_LIMITEDOver the per-reseller rate limit (300/min read, 60/min write); see Retry-After

All errors share one envelope:

json
{ "error": { "code": "INSUFFICIENT_BALANCE", "message": "Account balance is insufficient for this order" } }

Products

GET /products

Returns the products enabled for your account, with your unit prices.

bash
curl -s https://hellworld.io/openapi/v1/products \
  -H "Authorization: Bearer $KEY"
json
{
  "data": [
    {
      "product_code": "MOBILE-ET",
      "display_name": "ET Mobile",
      "category": "mobile",
      "billing_unit": "gb",
      "unit_price": 2.50,
      "currency": "USD"
    },
    {
      "product_code": "RES-GEOFAST",
      "display_name": "Geofast",
      "category": "residential",
      "billing_unit": "gb",
      "unit_price": 0.30,
      "currency": "USD"
    }
  ]
}

unit_price is your negotiated reseller price per billing_unit. If a product shows no unit_price, the platform default price applies at order time.

Balance

GET /balance

bash
curl -s https://hellworld.io/openapi/v1/balance \
  -H "Authorization: Bearer $KEY"
json
{ "balance": 152.40, "currency": "USD" }

Topping up: log into your account on hellworld.io and use the normal balance recharge (PayPal / crypto / other supported channels), or arrange an offline payment with your account manager — it is credited to the same balance the API spends from.

Orders

POST /orders

Places an order paid from your prepaid balance. Requires an Idempotency-Key header — 1–64 ASCII characters; allowed characters are A–Z, a–z, 0–9, ., _, : and - (spaces are not allowed; a UUID fits). Anything else is rejected with 422 IDEMPOTENCY_KEY_INVALID.

bash
curl -s -X POST https://hellworld.io/openapi/v1/orders \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-963d-1a4a6e4c1b2f" \
  -d '{ "product_code": "RES-GEOFAST", "quantity": 10 }'
FieldTypeRequiredMeaning
product_codestringyesFrom GET /products
quantitynumberyesAmount in billing_unit (GB), must be > 0

Success — 200:

json
{
  "order_ref": "a1b2c3d4e5f6...",
  "state": "active",
  "total_amount": 3.00,
  "currency": "USD"
}

Traffic is added to your account's proxy credential for that product (see Proxies & Usage). Repeat purchases of the same product top up the same credential.

Accepted — 202 (manual review):

json
{
  "order_ref": "a1b2c3d4e5f6...",
  "state": "manual_review",
  "message": "Order was recorded but pending manual verification; do not retry this request"
}

202 means you were already charged — do NOT retry

A 202 manual_review response means the balance was deducted and the order was recorded, but automatic fulfillment needs manual confirmation. Retrying with a new Idempotency-Key would place (and charge) a second order. Poll GET /orders/{order_ref} until the state becomes completed.

Errors:

HTTPcodeMeaning
400IDEMPOTENCY_KEY_REQUIREDMissing Idempotency-Key header
422IDEMPOTENCY_KEY_INVALIDKey not 1–64 chars of A-Za-z0-9._:-
402INSUFFICIENT_BALANCETop up your balance first
404PRODUCT_NOT_FOUNDNo such product available for your account (unknown code, or not enabled for you)
422NO_DEALER_PRICEWhitelisted but no wholesale price set for this product — contact the operator
409 / 422IDEMPOTENCY_KEY_CONFLICTSee Idempotency
422VALIDATION_ERRORMissing/invalid product_code or quantity
422ORDER_REJECTEDOrder could not be created
500ORDER_STATE_UNKNOWNOutcome unverified — do NOT retry with a new key; poll GET /orders or contact support
403SANDBOX_KEY_DISABLEDSandbox keys are not usable yet — create a live key

Idempotency

Every POST /orders must carry an Idempotency-Key. Semantics:

SituationResult
Same key, same body, finished beforeThe original response is replayed (no duplicate charge)
Same key, same body, still processing409 IDEMPOTENCY_KEY_CONFLICT — wait, then repeat the same request to fetch the stored result
Same key, different body422 IDEMPOTENCY_KEY_CONFLICT — a key can only ever be used for one request body
Request failed with a validation-type error (VALIDATION_ERROR, PRODUCT_NOT_FOUND, INSUFFICIENT_BALANCE, …)The error is replayed for that key; these are proven side-effect-free — retry with a new key
Request ended in ORDER_STATE_UNKNOWNOutcome could not be verified. Never retry with a new key (possible double charge) — poll GET /orders, or contact support quoting the key

Generate a fresh UUID per order attempt and persist it with your local order record. Keys must match [A-Za-z0-9._:-]{1,64} — max 64 characters, no spaces.

GET /orders

Paginated order history (newest first).

bash
curl -s "https://hellworld.io/openapi/v1/orders?pageNum=1&pageSize=20" \
  -H "Authorization: Bearer $KEY"
json
{
  "data": [
    {
      "order_ref": "a1b2c3d4e5f6...",
      "order_no": "CZ20260825...",
      "state": "completed",
      "total_amount": 3.00,
      "currency": "USD",
      "created_at": "2026-08-25 10:12:03",
      "products": [
        { "product_code": "RES-GEOFAST", "display_name": "Geofast", "quantity": 10 }
      ]
    }
  ],
  "pagination": { "page": 1, "page_size": 20, "total": 42 }
}

pageSize is capped at 100.

GET /orders/

Single order lookup — use this to poll the outcome of a 202 manual_review order.

bash
curl -s https://hellworld.io/openapi/v1/orders/a1b2c3d4e5f6 \
  -H "Authorization: Bearer $KEY"

Returns the same object shape as the list endpoint. 404 ORDER_NOT_FOUND if the ref does not exist or does not belong to your account.

Order states:

stateMeaning
pendingCreated, not yet paid
completedPaid; fulfillment done (traffic credited)
manual_reviewPaid; awaiting manual fulfillment confirmation — poll until completed
failedPayment failed; nothing charged
disputedUnder payment dispute
refundedRefunded
unknownAny other internal state

Proxies & Usage

GET /proxies

Your proxy credentials with live traffic usage — one entry per enabled product you have purchased.

bash
curl -s https://hellworld.io/openapi/v1/proxies \
  -H "Authorization: Bearer $KEY"
json
{
  "data": [
    {
      "product_code": "RES-GEOFAST",
      "display_name": "Geofast",
      "billing_unit": "gb",
      "username": "hw_ab12cd34",
      "password": "s3cr3tPass",
      "traffic": { "limit_gb": 50.0, "used_gb": 12.345, "remaining_gb": 37.655 },
      "status": "active",
      "expires_at": null
    }
  ],
  "usage_refresh_seconds": 60
}
FieldMeaning
username / passwordCredentials for the product's proxy gateway (formats below)
traffic.limit_gbTotal GB ever purchased (topped up cumulatively)
traffic.used_gbGB consumed
traffic.remaining_gblimit - used, floored at 0
statusactive, or suspended (e.g. traffic exhausted)
expires_atnull for never-expiring GB balances

Usage freshness

Usage is refreshed at most once per 60 seconds per account; within that window the last-known values are returned. Polling GET /proxies more often than once a minute yields no fresher data — a 1-minute poll loop is the recommended maximum.

Buying more of the same product (POST /orders) increases limit_gb on the same credential — you do not get a new username per order.

Proxy Formats

Build proxy strings with the username / password from GET /proxies. Country targeting and sticky sessions are encoded in the username.

ET Mobile (MOBILE-ET)

Gatewayetmobile.hellworld.io
Port5000
ProtocolsHTTP / HTTPS

Rotating (new IP per request):

etmobile.hellworld.io:5000:USERNAME-country-us:PASSWORD

Sticky session (same IP for the TTL):

etmobile.hellworld.io:5000:USERNAME-country-us-sid-a1b2c3d4-ttl-10m:PASSWORD
  • -country-<cc> — optional 2-letter country code, lowercase (omit for global random)
  • -sid-<id> — any 8-char alphanumeric session ID; same sid = same IP
  • -ttl-<N>m — session lifetime in minutes
bash
curl -x etmobile.hellworld.io:5000 \
  -U "USERNAME-country-us-sid-a1b2c3d4-ttl-10m:PASSWORD" \
  https://ipinfo.io

Geofast (RES-GEOFAST)

Gatewaygeofast.hellworld.io
Port (HTTP/HTTPS)6969
Port (SOCKS5)9696

Rotating:

geofast.hellworld.io:6969:USERNAME-country-US:PASSWORD

Sticky session (~10 min, same session = same IP):

geofast.hellworld.io:6969:USERNAME-country-US-session-a1b2c3d4e5:PASSWORD
  • -country-<CC> — optional 2-letter country code, uppercase (omit for global random)
  • -session-<id> — any 10-char alphanumeric session ID
bash
curl -x geofast.hellworld.io:6969 \
  -U "USERNAME-country-US-session-a1b2c3d4e5:PASSWORD" \
  https://ipinfo.io

For SOCKS5 use port 9696 with the same username syntax.

Custom Gateway Domain (White-label)

By default your customers connect to the shared gateway hostnames above (etmobile.hellworld.io, geofast.hellworld.io). If you want them to connect through your own branded domain, add a CNAME record pointing at our gateway — no code changes, and no impact on speed.

Setup

Add one CNAME per gateway you use, pointing at our gateway hostname:

Your recordTypeTarget
mproxy.yourbrand.comCNAMEetmobile.hellworld.io
proxy.yourbrand.comCNAMEgeofast.hellworld.io

Customers then connect exactly as before, swapping only the hostname — ports and username syntax are unchanged:

proxy.yourbrand.com:6969:USERNAME-country-US-session-a1b2c3d4e5:PASSWORD

Rules

  • Always CNAME to our *.hellworld.io gateway hostname (e.g. geofast.hellworld.io) — never to a raw IP address. We may update the gateway's underlying IPs at any time; because your record points at our hostname, those changes are picked up automatically with no action on your side. A record pinned to a fixed IP will break when the IP changes.
  • DNS-only — do NOT put a CDN/proxy layer in front (e.g. Cloudflare's orange-cloud). Proxy ports are raw TCP; routing them through a CDN breaks the connection. Keep the record grey-cloud / DNS-only.
  • Ports stay the same (ET Mobile 5000, Geofast HTTP 6969 / SOCKS5 9696).
  • Credentials are still issued by this API — a custom domain only rebrands the hostname; the username / password always come from GET /proxies.

Does it affect speed?

No. A custom domain is a pure DNS alias — proxy traffic still goes directly to the gateway IP and never passes through our servers or the extra hostname. The added CNAME hop only affects the first DNS lookup (a few milliseconds, then cached); actual proxy latency and throughput are identical to using the shared hostname.

Webhooks

Get notified when an API order is created, instead of polling. Configure the target URL in the Reseller Portal (Webhook section) — you receive a signing secret there.

Event: order.created — sent after an API order is recorded (active or manual_review):

json
{
  "event_type": "order.created",
  "event_id": "…",
  "dealer_uuid": "…",
  "created_at": "2026-08-25T10:12:03Z",
  "data": {
    "order_ref": "a1b2c3d4e5f6...",
    "state": "active",
    "total_amount": 3.00,
    "currency": "USD"
  }
}

Signature — every delivery carries:

X-Dealer-Signature: sha256=<hex>

where <hex> is HMAC-SHA256(webhook_secret, raw_request_body). Verify before trusting:

js
const crypto = require('crypto');
function verify(rawBody, header, secret) {
    const expected = 'sha256=' + crypto.createHmac('sha256', secret)
        .update(rawBody).digest('hex');
    return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}

Delivery & retries: your endpoint must return 2xx within a few seconds. Failed deliveries are retried with exponential backoff (30s, 60s, 120s, … capped at 1h) up to 12 attempts, then dropped. Use the portal's Test webhook button to verify your endpoint (webhook.test event).

TIP

Webhooks are best-effort push. For a guaranteed view of order outcomes (especially manual_review transitions), poll GET /orders/{order_ref}.

Error Reference

HTTPcodeWhereMeaning
400IDEMPOTENCY_KEY_REQUIREDPOST /ordersMissing Idempotency-Key header
422IDEMPOTENCY_KEY_INVALIDPOST /ordersKey not 1–64 chars of A-Za-z0-9._:-
401AUTH_MISSING_KEYallNo Authorization header
401AUTH_INVALID_KEYallMalformed/unknown key or bad secret
401AUTH_KEY_REVOKEDallKey revoked
401AUTH_KEY_EXPIREDallKey expired
402INSUFFICIENT_BALANCEPOST /ordersPrepaid balance too low
403DEALER_SUSPENDEDallReseller account disabled
404PRODUCT_NOT_FOUNDPOST /ordersNo such product available for your account
422NO_DEALER_PRICEPOST /ordersWhitelisted but no wholesale price set — contact the operator
404ORDER_NOT_FOUNDGET /orders/No such order on your account
409IDEMPOTENCY_KEY_CONFLICTPOST /ordersSame key still processing — repeat later
422IDEMPOTENCY_KEY_CONFLICTPOST /ordersSame key, different body
422VALIDATION_ERRORPOST /ordersBad product_code / quantity
422ORDER_REJECTEDPOST /ordersOrder refused
429RATE_LIMITEDallOver per-reseller limit (300/min read, 60/min write); see Retry-After
500INTERNAL_ERRORanyUnexpected server error
500ORDER_STATE_UNKNOWNPOST /ordersOutcome unverified — never retry with a new key; poll GET /orders
403SANDBOX_KEY_DISABLEDallSandbox keys are disabled until the sandbox launches

FAQ


How do I become a reseller / get products enabled?

Reseller accounts are set up by our team: your account is registered as a reseller, products are whitelisted, and your pricing is configured. Contact support or your account manager.


How do I pay?

The API spends your prepaid account balance. Top up online (log into hellworld.io → balance recharge: PayPal, crypto, and other supported channels) or arrange an offline payment with your account manager.


I placed an order but GET /proxies shows nothing.

GET /proxies only lists products that are (a) enabled for your account and (b) already purchased at least once. Right after your first order it can take a moment for the credential to be provisioned — check GET /orders/{order_ref} is completed, then retry.


Does every order create a new proxy account?

No. Purchases of the same product accumulate on one credential per product — limit_gb grows, the username stays the same.


How fresh is used_gb?

Usage is refreshed at most once per 60 seconds per account (usage_refresh_seconds in the response). Poll at most once a minute.


I got 202 manual_review — was I charged?

Yes. The order is recorded and your balance was deducted; fulfillment just needs a manual confirmation on our side. Do not retry with a new Idempotency-Key (that would be a second, separate order). Poll GET /orders/{order_ref}.


Is there a sandbox?

Not yet — sandbox keys are currently rejected on all API calls (403 SANDBOX_KEY_DISABLED). A mock sandbox is planned.


Can I get more products over the API?

Yes — any catalogued product can be enabled for your account. Ask your account manager.

All-in-one proxy platform — Residential, Mobile, ISP & Unlimited proxies.