ZoltVPN is one of the few VPN providers offering a complete reseller API. Instead of copying data between our reseller portal and your own CRM, billing system or shop, your software can read the plans and prices assigned to you, see every client and when their plan expires, buy subscriptions, extra devices, static IPs and subscription codes from your wallet, and receive signed webhooks the moment something happens. It can even send push notifications to your clients' devices. Everything is documented in the Reseller API wiki, with a public OpenAPI 3 description you can load into your tools.
What you can automate
The API mirrors what you already do in the portal, so anything repetitive can move into your own systems.
| Task | Endpoint | Scope |
|---|---|---|
| Your account, wallet and limits | GET /me | read |
| The plans you may sell, with your price and the retail price | GET /plans | read |
| What a purchase would cost right now | GET /quote | read |
| Clients, their plan, expiry, devices and usage | GET /clients | read |
| Daily traffic and traffic per location | GET /clients/{id}/usage | read |
| Create a client, optionally with a plan | POST /clients | purchase |
| Renew, or change the plan | POST /clients/{id}/extend | purchase |
| Extra devices until the client's expiry | POST /clients/{id}/devices | purchase |
| A static IP until the client's expiry | POST /clients/{id}/static-ip | purchase |
| Extra-data packs | POST /clients/{id}/data-addons | purchase |
| Buy or void subscription codes | POST /codes, POST /codes/{id}/void | purchase |
| Suspend, resume or disconnect a client | POST /clients/{id}/suspend and others | manage |
| Push notifications to your clients | POST /notifications | notify |
| Wallet balance and transactions | GET /wallet | read |
Keys and scopes
Getting a key
API access is switched on per reseller account: ask your account manager. Then, in the portal, open API → Keys → Create key and choose a name (for example "My CRM"), the scopes, an optional expiry and optional allowed IP addresses.
The key is shown once. We store only a fingerprint of it, so nobody, including us, can display it again. If you lose it, revoke it and create a new one.
What a key can reach
- A key works only on the Reseller API. It can't sign in to the portal or any other part of ZoltVPN.
- It reaches only your own account: your plans, your wallet and your clients.
- Reads include your own clients and your sub-agents' clients, with a field telling them apart. Purchases are only for your own direct clients, as in the portal.
Scopes
- read: every
GET: account, plans and prices, clients and expiry, usage, codes and wallet. Every key has it. - purchase: everything that charges your wallet: new clients, renewals, extra devices, static IPs, extra data and codes.
- manage: support actions: suspend, resume and disconnect a client.
- notify: push notifications to your clients.
Give each key only what it needs. A reporting dashboard needs read and nothing else.
Conventions that keep integrations simple
- JSON in and out, UTF-8,
camelCasefield names. - Money is in integer US cents, in fields ending in
Cents, so there are no rounding surprises. - Times are ISO-8601 in UTC. Data amounts are in bytes. Ids are UUIDs.
- Lists are paged with
pageandpageSize, up to 200 items per page. - Billing terms are
monthly,6monthandyearly. - New fields can be added, but fields are never renamed or removed within version 1, so your integration won't break unexpectedly.
Buying safely: quotes and idempotency
Money moves when you call a purchase endpoint, so the API is built to make mistakes hard.
Quote first. GET /quote tells you whether a purchase is possible and exactly what it would cost, including your balance afterwards. If something can't be sold, the answer says why.
Retry without paying twice. Every POST accepts an Idempotency-Key header, any unique string such as a UUID. If the same key arrives again within 24 hours, you get the first answer back and nothing is charged a second time. That covers time-outs, dropped connections and retries. Here's a renewal:
curl -s -X POST https://app.zoltvpn.com/api/reseller-api/v1/clients/CLIENT_ID/extend \
-H "Authorization: Bearer $ZOLT_API_KEY" \
-H "Idempotency-Key: 6f0c7b6e-2b1a-4d1e-9a51-0c6a3b1f2e77" \
-H "Content-Type: application/json" \
-d '{"planId":"PLAN_ID","billingInterval":"monthly"}'
Renewing on the same plan starts the new term when the current one ends, so your client loses no days. Switching to a different plan needs an explicit confirmation flag, because the new plan starts immediately.
Rate limits
By default, your account can make 60 calls a minute and 10,000 calls a day (UTC). Over the per-minute limit, calls answer 429 with a Retry-After header. Going over the daily limit blocks the API for your account for 24 hours. Every response carries headers showing what you have left, and GET /me shows your limits, which your account manager can adjust.
To stay comfortably inside them:
- page through
GET /clientssorted by expiry instead of fetching clients one by one; - cache
GET /plans, because prices change rarely; - back off exponentially on
429and server errors, rather than retrying in a tight loop.
A CRM sync in three calls
- Once a day, call
GET /plansto refresh your price list. - Page through
GET /clients?sort=expiresAt&dir=asc&status=liveto see who ends soon. - For each renewal your customer has paid you for, call
GET /quote, thenPOST /clients/{id}/extendwith anIdempotency-Key.
That's enough to keep a CRM accurate and renewals on time, without anyone copying data by hand.
Webhooks and push notifications
Polling only gets you so far. Webhooks let ZoltVPN call your server when something happens: a subscription code is redeemed, an extra-device code is used, a plan renews or is about to expire, or your wallet runs low. Each event is signed with a secret only you and we know, so your server can prove it came from us. The webhooks guide lists every event and shows how to check signatures.
Push notifications let your CRM send its own messages to your clients' devices, for example a renewal reminder in your own words, through POST /notifications with the notify scope. They are available on accounts where you handle client follow-up yourself; see the push notifications guide.
Keeping your key safe
- Store it in your server's secret store or environment, never in source control, a browser or a mobile app.
- Use one key per system, so you can revoke one without stopping the others.
- Set allowed IPs and an expiry where you can.
- Check API → Activity in the portal: every call is recorded with its time, path, result and calling address.
- If a key may have leaked, revoke it at once. It stops working on the next call.
FAQ
Who can use the Reseller API?
ZoltVPN resellers whose account has API access switched on. If you're not a reseller yet, our guide to starting a VPN reseller business explains the program.
Is there a machine-readable specification?
Yes. A public OpenAPI 3 description is linked from the wiki, so you can generate a client library or import the API into your testing tools.
What happens if my server retries a purchase after a time-out?
If you send the same Idempotency-Key, you get the original answer back and are not charged again.
Can I manage my sub-agents' clients through the API?
You can read them, as you can in the portal. Purchases are only for your own direct clients.
Ready to connect your systems? Ask your account manager to switch on API access, reach us through the business page, or download ZoltVPN to try the apps your clients will use, free for 7 days.



