Connect your backend to reseller products, wallet data, services, orders, hosting, VPN, invoices, SIM inventory, and endusers through one supported API client.
Use your active reseller bearer token. VPN has its own checkout, not POST /api/v1/orders.
GET /api/v1/products includes vpn_offers_url for discovery; VPN offers have plan keys, not generic product IDs.
GET /api/v1/vpn/offers lists Protector (R99), Shield (R179), and Armor+ (R279). Cash pricing applies your discount once and prorates remaining SAST calendar days. Shield also offers 250 OWP for 30 days.POST /api/v1/vpn/quotes with {"plan_key":"shield","payment_mode":"cash"} returns a signed quote valid for 15 minutes. Review its exact price and shared terms. Quoting does not reserve capacity, charge you, or contact the provider.POST /api/v1/vpn/checkouts. Explicitly accept the shared terms. After a timeout, poll or retry the exact same UUID and checkout identity, never create another purchase reference.200 means an allocation and one committed payment receipt. 202 means a durable funded request, no reseller payment yet. The dedicated worker prepares capacity and can complete that request once while its reviewed quote and funds remain valid.GET /api/v1/vpn/requests/{request_key}; this reads local data only. A changed/expired quote or changed funds requires human review, a fresh quote, and explicit resubmission of the same request UUID. Unfulfilled demand expires after 24 hours; one pending request per reseller.from uuid import uuid4
quote = client.vpn_quote(plan_key="shield", payment_mode="cash")
# Present quote["quote"] and quote["shared_terms"] for human review.
# Only after acceptance; persist this UUID before sending the purchase.
request_key = str(uuid4())
result = client.checkout_vpn(
request_key=request_key,
plan_key="shield",
signed_quote=quote["signed_quote"],
accept_shared_terms=True,
)
status = client.vpn_request(request_key)["request"]
# Only a fulfilled receipt confirms payment and allocation.
if status["status"] == "fulfilled":
allocation = client.vpn_allocation(status["allocation_id"])
# Credentials require a separate explicit sensitive read:
# client.vpn_credentials(status["allocation_id"]) # Never log the result.
GET /api/v1/vpn/requests finds pending requests. POST /api/v1/vpn/requests/{request_key}/cancel
cancels unfulfilled demand only: a completed receipt wins the race, without a refund or service cancellation.
GET /api/v1/vpn/allocations?limit=50&offset=0 lists owned cash and points allocations.
Shield OWP grants do not renew automatically or create a cash service. For an explicit renewal of a current, unexpired grant,
obtain a fresh points quote and submit a new checkout UUID with renew_allocation_id and the allocation's original
enduser_id (or null). This adds 30 days to its old expiry. Cash allocations renew through ordinary monthly billing.
Credentials are shared, not individually isolated. Protector/Shield allow one connection; Armor+ allows two. Country and network restrictions are declared terms, configured externally, not enforced by an API field. Allocation metadata contains no passwords; the separate credentials endpoint requires an active owned entitlement. All VPN responses are private/no-store/no-referrer. Never log signed quotes or credentials, expose them in URLs, or treat a queued request as purchased access. No master inventory, provider keys or provider management endpoints are public.
Cloud PBX products expose cloud_pbx metadata in GET /api/v1/products.
The 50-, 100- and 500-minute plans include four concurrent calls each; unlimited plans include one or two as stated.
Voice/SIP/VoIP orders need no SIM and remain in Pending Orders for admin QR upload and host/SIP provisioning; the API does not auto-activate them.
Android users must use the OpenWeb PBX app, not 3CX; setup instructions and the download are supplied with activation.
Authorize with a reseller bearer token and inspect schemas. This reference targets production: submitting purchases can charge your wallet or OWP and queue billable capacity. Use read-only operations unless you intend to buy.