The FoxyProxy Reseller API, Non-Leasing is a RESTful interface for resellers to resell VPN servers, proxy servers, and customer accounts on those servers. Reselling can be done on your website or within your software product. Supported services include a variety of VPN protocols and proxy protocols.

This API is similar to, but distinct from, the FoxyProxy Reseller API, Leasing. The primary difference is this API does not ensure that each node is dedicated to a single account. You can share nodes among any number of accounts if that is your plan. There are other differences between the two APIs. Some examples:

  • No email addresses or other PII is collected by this API

  • Authentication is different

  • Some JSON objects may differ

  • Content-Types are different

This is not a comprehensive list of differences.

Although they appear similar, and some concepts are shared, the two FoxyProxy Reseller APIs are not interchangeable and have significant differences

Introduction

There are two objects upon which you can operate: nodes and accounts (account history coming soon). A node represents a device on which a VPN server and/or proxy server is running. An account represents a username/password on one or more nodes (vpn/proxy servers). Accounts are used to authenticate with nodes. Account history and account metadata (e.g. bandwidth consumption) are not yet available in this API but are tracked.

You should also be aware of the concept of your reseller pool. Reseller pool is the list of nodes (or vpn/proxy servers) that your account can use. You may have 1 or 10,000 or any number of nodes in your pool. Currently, reseller pools can be only expanded/reduced by contact with FoxyProxy Support, not through this API.

You use this API to create accounts for your customers. When first created, an account has access to the array of nodes you pass to the API during creation or, if you do not specify any array, the account is given access to all nodes. You can also use this API to: list nodes in your reseller pool, activate, deactivate, and delete customer accounts, change passwords, and change usernames. Your customers can use this API to enumerate their accounts and update their passwords.

Personally Identifiable Information (PII)

This API does not store any PII about your customers unless you choose to use email addresses for usernames. Passwords are stored using salted, SHA-512 one-way encryption with multiple passes. For this reason, passwords are unrecoverable. No data is logged about your customers except bandwidth use. That information is collected in order to isolate abusive customers (e.g. customers unintentionally part of a botnet or performing a denial-of-service attack on nodes in your reseller pool).

When deleting accounts, all records are permanently and unrecoverable purged from our systems.

Authentication

There are two different roles with which you can authenticate to the API:

ROLE_RESELLER

the administrative role with which you can create accounts, deactivate accounts, list all of your accounts and nodes, etc. All endpoints documented in this API are callable with this role.

ROLE_USER

your customer’s role which is limited to enumerating account info for the authenticated username and updating associated passwords

ROLE_RESELLER

Upon signing up for the reseller service, FoxyProxy will issue you a username, password, and a domain. These are used to authenticate with the API using HTTP BASIC authentication and the custom HTTP header named X-DOMAIN. HTTP BASIC authentication allows for simpler auth than OAuth2 and is completely stateless and token-less, but at the cost of being inherently insecure since HTTP BASIC is only Base64-encoded without any encryption. Therefore, all API endpoints use HTTPS for encryption.

ROLE_USER

Your customers can authenticate against this API and use it in limited ways. This is provided so you can write applications for your customer, and he can retrieve account/node information for use within that application or update his password. When your customers authenticate over HTTPS using the X-DOMAIN HTTP header we assigned you, along with their HTTP BASIC username/password, they can call a very limited subset of the endpoints in this API. Currently, that is limited to Get Accounts, Get Accounts By Username, and Update Passwords. The first two endpoints do the same thing for ROLE_USER and are interchangeable.

Availability

API and VPN/proxy services are restarted approximately 90 days in order to renew SSL certificates. Downtime during this period is approximately 3 seconds per node. VPN/proxy services are unavailable during downtime, but API services are available. Unfortunately, existing VPN connections are terminated and must be re-established after the VPN services are restored. Notifications can be sent to alert you of forthcoming restarts.

Available Services

Different types of VPN and proxy services can be resold. You can offer some or all of these to your customers:

  • IPSec/IKEv2

  • IPSec/Cisco

  • IPSec/L2TP

  • OpenVPN

  • PPTP

  • HTTP Proxy

  • SSL Proxy

  • SOCKS5 Proxy

  • ShadowSocks

Some of these services work with IPv6 and some do not. Contact us for details.

Custom Domain Name

If you call this API from your application installed on your customers' devices, the customer may become aware of calls to FoxyProxy domains. This may raise suspicion unless you inform your customers about the purpose of these calls. You can therefore expose this API under your own domain name with our cooperation. You can also expose nodes (servers) in your reseller pool using your own domain names.

UTF-8 Support

Usernames and password can be any combination of UTF-8 characters. Non-ASCII characters work for all services resold by FoxyProxy except the PPTP VPN protocol (likely due to its significant age). Please keep this in mind if you plan to resell PPTP VPN service.

API Versioning

The current version of this API is called v2. The API uses the HTTP Content-Type header so that clients can request different API versions:

application/vnd.foxyproxy.reseller.api-nonleased.v2+json

means use exactly v2 of the API, even if there are newer versions

future

other Content-Types will be added as new API versions with breaking changes are released. Non-breaking versions may use the same Content-Type.

Endpoints

The examples in this document use domain.com for all endpoints. That domain is fictitious and does not work with this API. You will be given test and production API endpoints after registration.

All endpoints share these common HTTP request headers:

Table 1. HTTP Request Headers
Name Value Required?

X-DOMAIN

Provided by FoxyProxy

Yes

Authorization

HTTP Basic Auth provided by FoxyProxy and encoded like this

Yes

Content-Type

application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8

Yes

Accept

application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8

No

Accounts

An account represents a customer who can be assigned to one or more nodes (vpn/proxy servers). Each account is assigned to a single node and is used to authenticate against and use a vpn/proxy server on that node. Accounts that you create will often share the same username on different nodes.

Typically, each of your customers will have multiple accounts (one per node). Each of those accounts can share the same username and password for simplicity.

This section describes the endpoints and verbs used to create, read, update, and delete (CRUD) accounts.

Example Account

{
  "uid": "5b09a8dd-16fe-4e13-9407-e169f7f869ec",
  "active": true,
  "username": "johnConnor86",
  "node": { /* omitted for simplicity */ }
}

Active and Inactive

Accounts can be active or inactive. An inactive account cannot use the node to which it is assigned, but the customer can still call API endpoints such as Get Accounts. You can activate/deactivate accounts based on customer payments, for example. When a customer fails to pay, you can deactivate his account. If he decides to pay a few days later, you can activate his accounts again. If he does not pay after several months, you can delete his accounts altogether (although this is not recommended because account history and bandwidth accounting is permanently lost). You can also deactivate his account on only some nodes, and not others, if you suspect abuse or want to restrict the customer for other reasons — perhaps you sell tiered access where customers only receive access to a subset of servers unless they pay full price.

Common API properties

Account operations which write/change data (create, update, delete) accept an optional JSON object in the HTTP request body. There are two JSON properties common to all of these API endpoints: nodenames and comment.

nodenames property

The nodenames property is a JSON array. It limits the effect of the current create, update, or delete operation to the set of nodes in the JSON array. If omitted, the current create, update, or delete operation applies to the specified username for all nodes in your reseller pool.

comment property

The comment property is a JSON string. Use it to save an optional reason or note for the current operation. For example, if you deactivate an account, you might add a comment such as User filed credit card chargeback. See ticket 9108832. Comments can be retrieved using the future GET /accounts/history/{username} operation. Comments are limited to 512 characters each. Future API release may also permit comments to be associated with an account itself, rather than just actions on accounts (account history).

Do not save personally identifiable information in comments

Create Accounts

POST /accounts/

Requires ROLE_RESELLER privilege.

An account is a username/password on one node. This endpoint creates accounts on one or more nodes with the specified username/password. If the optional nodeNames array in the JSON HTTP request body is missing or the length of the array is 0, then accounts are created on all nodes in your reseller pool (unless the username already exists; read below for details).

Accounts are created in the active state by default, but active in the JSON HTTP request body can be specified as 0 to create the accounts in the inactive/deactivated state. A value of 1 for active (the default) means the accounts are created in the active state.

An optional comment can be specified in the JSON HTTP request body. Comments are arbitrary strings that you can use for notes about accounts. This comment, if specified, is stored in the account’s history, accessed from the GET /accounts/history/{username} operation (not yet available). The comment is not stored for accounts that already exist before this call. Each comment is limited to 512 characters. Future API release may also permit comments to be associated with an account itself, rather than just actions on accounts (account history).

Password Restrictions

The password you send in the JSON HTTP request body should be unencrypted. It is stored using salted, SHA-512 one-way encryption with multiple passes. For this reason, the password is unrecoverable. Passwords must be between 3 and 16 characters, inclusive.

Username Restrictions

Usernames are unique per node. They cannot be changed after creation. (we may add this ability later). You cannot create the same username more than once on the same node. Use Username Exists to determine if username is already in use for any node. Usernames cannot contain colon (:) since that is reserved as an HTTP Basic authentication delimiter. Usernames must be between 3 and 16 characters, inclusive.

Non-ASCII characters are currently untested for some VPN and proxy protocols. This API supports non-ASCII characters in both usernames and passwords, and won’t complain about them, but depending on the VPN or proxy protocol, authentication may fail with non-ASCII characters. Please contact us if you’d like confirmation that non-ASCII characters will work for your system.
HTTP Response

As long as at least one account is created, the returned HTTP status code is 200. The JSON response body is an array of accounts. It includes both newly created accounts as well as any accounts for the specified nodes* that already existed with the given username before this call.

*specified nodes: the set of nodes if you called this API function with an optional nodeNames array OR all nodes in your reseller pool if nodeNames was omitted from the request. See the nodenames property section.

Here is an example response:

[
  {
    "uid": "13837902-33aa-4804-ae5a-7ece5bbcf8bc",
    "active": true,
    "username": "johnConnor88",
    "alreadyExists": true, (1)
    "node": {
      "active": true,
      "name": "test-node-it1", (2)
      "ipAddress": "89.22.109.41",
      "country": "Milan",
      "countryCode": "IT",
      "city": "Italy",
      "services": [ (3)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            8903,
            12951
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            43,
            266
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            515
          ]
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
        }
      ]
    }
  }
]
1 This username already existed on this node before this call. The account was not created or changed in any way as a result of this call.
2 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
3 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.
You should confirm the returned number of accounts is what you expect. A count lower than expected indicates an internal error and that not accounts could be created.
What if the username already exists?

If username already exists on some of the specified nodes (or all nodes if the optional nodeNames array in the JSON HTTP request body is omitted):

  • Accounts are only created on nodes which do not already have an account with the specified username

  • For accounts that already exist on nodes, comment is not stored.

  • For accounts that already exist on nodes, password and active status are not changed regardless of whether the values you specify in this call match the existing state of the accounts. To update existing accounts, you must use update passwords, activate accounts, and deactivate accounts.

  • On the returned JSON object, the alreadyExists property will be true for accounts that already existed prior to this call. If the account was created as a result of this call, the alreadyExists property will not be present in the returned JSON object.

  • If all nodes already have an account with the specified username, HTTP status 400 is returned with the this JSON:

{
  "exceptionId": "AccountsNotCreated",
  "error": "Bad Request",
  "message": "Accounts not created",
  "status": 400,
  "errors": [
    {
      "field": null,
      "code": "accounts.not.created",
      "message": "Accounts not created"
    }
  ]
}
If an account already exists, it is not updated when using this API function.

HTTP status code is 404 returned if (1) you do not have any nodes in your reseller pool or (2) none of the nodes you specified in the optional nodeNames array are in your reseller pool. If the optional nodeNames array contains some nodes which are in your reseller pool and some which are not, the nodes not in your pool are ignored.

Create accounts with username johnConnor88 on all nodes
curl example
$ curl 'https://domain.com/accounts/' -i -X POST \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"username":"johnConnor88","password":"hunterkiller2","comment":"free account for beta user"}'}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON with the username, password, and optional comment to create. The comment is associated with this account action (create), not the account itself, and is retrieved with GET /accounts/history/{username} (not yet available). Since nodeNames array is not specified, the account is created on all nodes in the reseller pool resulting in n accounts where n is the number of nodes in the reseller pool

For examples, we keep the number of nodes small. This reseller has only two nodes, but in reality most resellers have many more. So here two accounts are created:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "uid": "13837902-33aa-4804-ae5a-7ece5bbcf8bc",
    "active": true,
    "username": "johnConnor88",
    "node": {
      "active": true,
      "name": "test-node-it1", (1)
      "ipAddress": "89.22.109.41",
      "country": "Milan",
      "countryCode": "IT",
      "city": "Italy",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            8903,
            12951
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            43,
            266
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            515
          ]
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
        }
      ]
    }
  },
  {
    "uid": "6011b48c-81c2-4cf5-b47d-2a07a435a289",
    "active": true,
    "username": "johnConnor88",
    "alreadyExists": true, (3)
    "node": {
      "active": true,
      "name": "test-node-de1", (1)
      "ipAddress": "123.41.54.2",
      "country": "Germany",
      "countryCode": "DE",
      "city": "Berlin",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNV3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            6502,
            13301
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            999,
            1121
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            1080,
            36
          ]
        }
      ]
    }
  }
]
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.
3 This username already existed on this node before this call. This account was not created or changed in any way as a result of this call.
Create accounts with username johnConnor85 on only one node

By specifying an array of nodeNames, you can choose to create new accounts on selected nodes instead of all nodes.

curl example
$ curl 'https://domain.com/accounts/' -i -X POST \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"username":"johnConnor85","password":"hunterkiller2", "nodeNames": ["test-node-de1"]}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON of the accounts to create on the one named node, includes the username, password, nodeNames array and an optional comment (omitted)

One account is created:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "uid": "122fdab6-60da-425c-8d36-c7b97c62420a",
    "active": true,
    "username": "johnConnor85",
    "node": {
      "active": true,
      "name": "test-node-de1", (1)
      "ipAddress": "123.41.54.2",
      "country": "Germany",
      "countryCode": "DE",
      "city": "Berlin",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            6502,
            13301
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            999,
            1121
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            1080,
            36
          ]
        }
      ]
    }
  }
]
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.
Create accounts with username johnConnor85 on only two nodes in the inactive state

By specifying an array of nodeNames, you can choose to create new accounts on selected nodes instead of all nodes. You can also optionally specify the active/inactive state with the active property. The default when not specified is 1 (active). Here we use 0 to create them in the inactive/deactivated state.

curl example
$ curl 'https://domain.com/accounts/' -i -X POST \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"username":"johnConnor85", "password":"hunterkiller2", "active": 0, "nodeNames": ["test-node-de1", "test-node-it1"]}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON with the username and password of the accounts to create on the two named nodes. active is 0 which means the accounts are created in the inactive/deactivated state. The optional comment (omitted) property is omitted.

Two accounts are created:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "uid": "91635249-df1d-4409-a356-785e2a50b0d6",
    "active": false, (1)
    "username": "johnConnor85",
    "node": {
      "active": true,
      "name": "test-node-de1", (2)
      "ipAddress": "123.41.54.2",
      "country": "Germany",
      "countryCode": "DE",
      "city": "Berlin",
      "services": [ (3)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            6502,
            13301
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            999,
            1121
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            1080,
            36
          ]
        }
      ]
    }
  },
  {
    "uid": "b1d4fa5c-f5bc-4dee-bb46-9f6ff69bf09c",
    "active": false, (1)
    "username": "johnConnor85",
    "node": {
      "active": true,
      "name": "test-node-it1", (2)
      "ipAddress": "89.22.109.41",
      "country": "Milan",
      "countryCode": "IT",
      "city": "Italy",
      "services": [ (3)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            8903,
            12951
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            43,
            266
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            515
          ]
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
        }
      ]
    }
  }
]
1 Notice the active flag is false because we created this account in the inactive state
2 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
3 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.

Get Accounts

GET /accounts/?index=xxx&size=yyy

Requires ROLE_USER or ROLE_RESELLER privileges.

Get at most size accounts beginning at the specified zero-based index. Maximum value for size is 100.

This endpoint can be called by customers or resellers. If the authenticated user is a reseller (ROLE_RESELLER), then all accounts are returned. If the authenticated user is a customer (ROLE_USER), then only accounts with the authenticated username are returned.

Accounts are sorted lexicographically by the node’s country name (account.node.country).

When called as ROLE_USER, this endpoint performs the same operation as Get Accounts By Username.
Get accounts as a customer
curl example
$ curl 'https://domain.com/accounts/?index=0&size=100' -i -X GET \ (1)
     --user johnConnor88:hunterkiller2 \ (2)
    -H 'X-DOMAIN: test-reseller-1' \ (3)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (4)
1 Minimum index is 0; max size is 100
2 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use customers’s credentials.
3 Provided to you by FoxyProxy
4 There is no HTTP body

Since we sent customer credentials and not reseller’s credentials, only the accounts with username johnConnor88 are returned. There are two results in this example:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "uid": "6abbc07b-fd48-48d3-8250-01d9aebf22e9",
    "active": true,
    "username": "johnConnor88",
    "node": {
      "active": true,
      "name": "test-node-it1", (1)
      "ipAddress": "89.22.109.41",
      "country": "Milan",
      "countryCode": "IT",
      "city": "Italy",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            8903,
            12951
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            43,
            266
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            515
          ]
        }
      ]
    }
  },
  {
    "uid": "8aff01d1-ad18-41b0-b082-ff38f9f88030",
    "active": true,
    "username": "johnConnor88",
    "node": {
      "active": true,
      "name": "test-node-de1", (1)
      "ipAddress": "123.41.54.2",
      "country": "Germany",
      "countryCode": "DE",
      "city": "Berlin",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            6502,
            13301
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            999,
            1121
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            1080,
            36
          ]
        }
      ]
    }
  }
]
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.
Get accounts as a reseller
curl example
$ curl 'https://domain.com/accounts/?index=0&size=100' -i -X GET \ (1)
     --user milesDyson:skynet101 \ (2)
    -H 'X-DOMAIN: test-reseller-1' \ (3)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (4)
1 Minimum index is 0; max size is 100
2 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use a reseller’s credentials.
3 Provided to you by FoxyProxy
4 There is no HTTP body

Since we sent reseller credentials, accounts with all usernames are returned. Accounts are sorted ascending by account uid (account.uid).

Get Accounts By Username

GET /accounts/{username}/?index=xxx&size=yyy

Requires ROLE_USER or ROLE_RESELLER privileges.

Get accounts with the specified username. At most size accounts are returned, beginning at the specified zero-based index. Maximum value for size is 100.

This endpoint can be called by customers or resellers. If the authenticated user is a customer (ROLE_USER), then username in the URL must match username in the HTTP Basic Authentication header. The response is limited to that single username. If the authenticated user is a reseller (ROLE_RESELLER), then username in the URL is unrestricted. Accounts are sorted lexicographically by the node’s country name (account.node.country).

When called as ROLE_USER, this endpoint performs the same operation as Get Accounts.
Get accounts by username as a customer
curl example
$ curl 'https://domain.com/accounts/johnConnor88/?index=0&size=100' -i -X GET \ (1)
     --user johnConnor88:hunterkiller2 \ (2)
    -H 'X-DOMAIN: test-reseller-1' \ (3)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (4)
1 Minimum index is 0; max size is 100
2 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use customers’s credentials and so the username specified in the HTTP Basic Authorization header must match the username in the URL
3 Provided to you by FoxyProxy
4 There is no HTTP body

Only the accounts with username johnConnor88 are returned. There are two results in this example:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "uid": "6abbc07b-fd48-48d3-8250-01d9aebf22e9",
    "active": true,
    "username": "johnConnor88",
    "node": {
      "active": true,
      "name": "test-node-it1", (1)
      "ipAddress": "89.22.109.41",
      "country": "Milan",
      "countryCode": "IT",
      "city": "Italy",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            8903,
            12951
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            43,
            266
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            515
          ]
        }
      ]
    }
  },
  {
    "uid": "8aff01d1-ad18-41b0-b082-ff38f9f88030",
    "active": true,
    "username": "johnConnor88",
    "node": {
      "active": true,
      "name": "test-node-de1", (1)
      "ipAddress": "123.41.54.2",
      "country": "Germany",
      "countryCode": "DE",
      "city": "Berlin",
      "services": [ (2)
        {
          "name": "ipsec/ikev2/standard"
        },
        {
          "name": "ipsec/cisco"
        },
        {
          "name": "ipsec/lt2p"
        },
        {
          "name": "openvpn",
          "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
        },
        {
          "name": "pptp"
        },
        {
          "name": "http-proxy",
          "ports": [
            6502,
            13301
          ]
        },
        {
          "name": "ssl-proxy",
          "ports": [
            999,
            1121
          ]
        },
        {
          "name": "socks5-proxy",
          "ports": [
            1080,
            36
          ]
        }
      ]
    }
  }
]
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.
Get accounts by username as a reseller
curl example
$ curl 'https://domain.com/accounts/kyleReese/?index=0&size=100' -i -X GET \ (1)
     --user milesDyson:skynet101 \ (2)
    -H 'X-DOMAIN: test-reseller-1' \ (3)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (4)
1 Minimum index is 0; max size is 100
2 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use a reseller’s credentials. The username in the URL can be any username
3 Provided to you by FoxyProxy
4 There is no HTTP body

We authenticated as the reseller. All accounts with the username kyleReese are returned.

Count Accounts

GET /accounts/count/

Requires ROLE_RESELLER privileges.

Gets the total count of accounts. This count includes duplicate usernames. For example, if the reseller has 40 nodes and 100,000 of the same usernames on each node, this method returns 4,000,000, not 100,000.

curl example
$ curl 'https://domain.com/accounts/count/' -i -X GET \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 There is no HTTP body
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 4000000}

Username Exists

GET /accounts/exists/{username}

Requires ROLE_RESELLER privileges.

Returns HTTP status 200 if the specified username exists on any node in your reseller pool. HTTP status 404 is returned if the specified username does not exist on any node in your reseller pool

curl example
$ curl 'https://domain.com/accounts/exists/kyleReese/' -i -X GET \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 There is no HTTP request body

The following response indicates the username does not exist on any nodes in your reseller pool:

HTTP response
HTTP/1.1 404 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
(1)
1 There is no HTTP response body

Deactivate Accounts

PATCH /accounts/deactivate/{username}

Requires ROLE_RESELLER privilege.

Deactivates accounts on one or more nodes and returns a count of affected accounts. If nodeNames array in the optional JSON HTTP request body is missing or length of the array is 0, then accounts with the specified username are deactivated on all nodes in your reseller pool. An optional comment can be specified in the JSON HTTP request body. Comments are arbitrary strings that you can use for notes about accounts. This comment, if specified, is stored in the account’s history, accessed from the GET /accounts/history/{username} operation (not yet available). Each comment is limited to 512 characters.

A count of the number of affected accounts is returned.

You should confirm the returned count is what you expect. A count lower than expected indicates an internal error and that not accounts could be updated.

The HTTP PATCH verb is used to signify this is partial update to one or more records (accounts), even though specifications like JSON Patch are not followed by this API.

This call only affects new connections to nodes. Accounts that are already connected to a node are not disconnected by this call. In other words, if an account has an active connection to a node, it will remain active an and functional until the connection drops. New connections will fail. Therefore, for long-lived VPN connections, after this call completes, the account may remain active and functional longer than you intend. Proxy connections are generally shorter-lived, except when streaming, but the same limitation applies to proxy and VPN connections alike.
Deactivate accounts with username johnConnor85 on all nodes
curl example
$ curl 'https://domain.com/accounts/deactivate/johnConnor85/' -i -X PATCH \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"comment": "user abused system, see ticket #9883201}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 The entire body is optional but this example specifies a comment property. The comment is associated with this account action (deactivate), not the account itself, and is retrieved with GET /accounts/history/{username} (not yet available). The lack of a nodeNames property indicates that accounts with this username on all nodes in the reseller pool should be deactivated, not a subset of all accounts.
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 3}
If you retrieve the accounts after deactivation, the active flag for those accounts is true.
Deactivate accounts with username johnConnor85 on only two nodes

By specifying an array of nodeNames, you can choose to deactivate accounts on selected nodes instead of all nodes.

curl example
$ curl 'https://domain.com/accounts/deactivate/johnConnor85/' -i -X PATCH \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"nodeNames": ["testnode-nl01", "testnode-uk01"]}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON HTTP request body specifying the nodes on which to deactivate. The optional comment property is omitted.

Two accounts are deactivated:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 2}

Activate Accounts

PATCH /accounts/activate/{username}

Requires ROLE_RESELLER privilege.

Activates accounts on one or more nodes and returns a count of affected accounts. If nodeNames array in the optional JSON HTTP request body is missing or length of the array is 0, then accounts with the specified username are activated on all nodes in your reseller pool. An optional comment can be specified in the JSON HTTP request body. Comments are arbitrary strings that you can use for notes about accounts. This comment, if specified, is stored in the account’s history, accessed from the GET /accounts/history/{username} operation (not yet available). Each comment is limited to 512 characters.

A count of the number of affected accounts is returned.

You should confirm the returned count is what you expect. A count lower than expected indicates an internal error and that not accounts could be updated.

The HTTP PATCH verb is used to signify this is partial update to one or more records (accounts), even though specifications like JSON Patch are not followed by this API.

Activate accounts with username johnConnor85 on all nodes
curl example
$ curl 'https://domain.com/accounts/activate/johnConnor85/' -i -X PATCH \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"comment": "user paid again, see ticket #7883201}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 The entire body is optional but this example specifies a comment property. The comment is associated with this account action (activate), not the account itself, and is retrieved with GET /accounts/history/{username} (not yet available). The lack of a nodeNames property indicates that accounts with this username on all nodes in the reseller pool should be activated, not a subset of all accounts.
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 3}
If you retrieve the accounts after activation, the active flag for those accounts is true.
Activate accounts with username johnConnor85 on only two nodes

By specifying an array of nodeNames, you can choose to activate accounts on selected nodes instead of all nodes.

curl example
$ curl 'https://domain.com/accounts/activate/johnConnor85/' -i -X PATCH \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"nodeNames": ["test-node-de1", "test-node-it1"]}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON HTTP request body specifying the nodes on which to activate. The optional comment property is omitted.

Two accounts are activated:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 2}

Update Passwords

PATCH /accounts/update-password/{username}

Requires ROLE_USER or ROLE_RESELLER privilege.

Updates the password on one or more nodes and returns a count of affected accounts. If the nodeNames array in the optional JSON HTTP request body is missing or length of the array is 0, then passwords for all accounts with the specified username on all nodes in your reseller pool are updated. An optional comment can be specified in the JSON HTTP request body. Comments are arbitrary strings that you can use for notes about accounts. This comment, if specified, is stored in the account’s history, accessed from the GET /accounts/history/{username} operation (not yet available). Each comment is limited to 512 characters.

A count of the number of affected accounts is returned.

You should confirm the returned count is what you expect. A count lower than expected indicates an internal error and that not accounts could be updated.

The password should be unencrypted. It is stored using salted, SHA-512 one-way encryption with multiple passes. For this reason, the password is unrecoverable. Passwords must be between 3 and 127 characters, inclusive. Passwords are sent in the JSON HTTP request body, not the URL, so that passwords aren’t accidentally logged or stored in browser history. This purposely breaks the pattern of the rest of this API.

This endpoint can be called by customers or resellers. If the authenticated user is a reseller (ROLE_RESELLER), then username in the URL is unrestricted. If the authenticated user is a customer (ROLE_USER), then only accounts with the authenticated username can be updated.

The HTTP PATCH verb is used to signify this is partial update to one or more records (accounts), even though specifications like JSON Patch are not followed by this API.

Update password for accounts with username johnConnor88 on all nodes
curl example
$ curl 'https://domain.com/accounts/update-password/johnConnor88' -i -X PATCH \
     --user johnConnor88:hunterkiller2 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"password": "ill2Be3Back4", "comment": "app forced password change after 90 days"}' (3)
1 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use customers’s credentials and so the username specified in the HTTP Basic Authorization header must match the username in the URL. The password is the current, unchanged password.
2 Provided to you by FoxyProxy
3 The new password is provided in a JSON HTTP request body. The optional comment is associated with this account action (update-password), not the account itself, and is retrieved with GET /accounts/history/{username} (not yet available). The lack of a nodeNames property indicates that accounts with this username on all nodes in the reseller pool should be updated, not a subset of all accounts.
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 5}
Update password for accounts with username johnConnor88 only two nodes

By specifying an array of nodeNames, you can choose a subset of accounts to be updated:

curl example
$ curl 'https://domain.com/accounts/update-password/johnConnor88' -i -X PATCH \
     --user johnConnor88:hunterkiller2 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"password": "ill2Be3Back4", "nodeNames": ["testnode-nl01", "testnode-uk01"]}' (3)
1 Generates the HTTP Basic Authentication header. This can be either reseller credentials or a customers’s credentials. In this example, we use customers’s credentials and so the username specified in the HTTP Basic Authorization header must match the username in the URL. The password is the current, unchanged password.
2 Provided to you by FoxyProxy
3 The new password is provided in a JSON HTTP request body. The JSON also includes a nodeNames array specifying only accounts on certain nodes to be updated. No optional comment is specified.

Two accounts are affected:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 2}

Delete Accounts

DELETE /accounts/{username}

Requires ROLE_RESELLER privilege.

Deletes accounts and, optionally, account history on one or more nodes and returns a count of affected accounts. If nodeNames array in the optional JSON HTTP request body is missing or length of the array is 0, then accounts with the specified username are deleted on all nodes in your reseller pool. If "includeHistory": true is included in the optional JSON HTTP request body, all account history entries are also deleted. If not specified or false, then account history is not deleted.

An optional comment can be specified in the JSON HTTP request body. Comments are arbitrary strings that you can use for notes about accounts. This comment, if specified, is stored in the account’s history, accessed from the GET /accounts/history/{username} operation (not yet available). Each comment is limited to 512 characters. If both "includeHistory": true and comment are specified, then comment is ignored and all history with comments are permanently deleted.

A count of the number of affected accounts is returned.

You should confirm the returned count is what you expect. A count lower than expected indicates an internal error and that not accounts could be deleted.
All information about deleted accounts are permanently and unrecoverably purged from our systems when you use this endpoint.
We discourage you from deleting accounts. Instead, consider deactivating them. This way, (1) you will have an accurate count of total accounts over time. (2) Deleting accounts means you have no record of bandwidth consumed by the deleted accounts. If a particular user is abusing your nodes, you may want to keep the records for that by not deleting accounts. We do not store anything about accounts except bandwidth use, username, and encrypted password.
Delete accounts with username johnConnor85 on all nodes
curl example
$ curl 'https://domain.com/accounts/johnConnor85/' -i -X DELETE \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"includeHistory": true}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 There is no nodeNames array. This indicates accounts with this username on all nodes in the reseller pool should be deleted, not a subset of all accounts. Account history is also deleted.

Two accounts are deleted:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 2}
Delete accounts with username johnConnor85 on only one node

By specifying an array of nodeNames, you can choose to delete accounts on selected nodes instead of all nodes.

curl example
$ curl 'https://domain.com/accounts/johnConnor85/' -i -X DELETE \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    --data '{"nodeNames": ["testnode-nl01"], "comment": "account created in error"}' (3)
1 Generates the HTTP Basic Authentication header. This must be the reseller’s credentials.
2 Provided to you by FoxyProxy
3 JSON HTTP request body specifying the nodes on which to delete. A comment is stored in the account history. Account history is not deleted since includeHistory is omitted.

One account is deleted:

HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 2}

Unresolved directive in index.adoc - include::dns-suffixes.adoc[]

Nodes

A node represents a device on which a VPN server and/or proxy server is running. This section describes the endpoints and verbs used to read information about the nodes in your reseller pool. There are no write operations for nodes.

Example Node

{
    "active": true,
    "name": "test-node-it1", (1)
    "ipAddress": "209.141.40.200",
    "country": "Milan",
    "countryCode": "IT",
    "city": "Italy",
    "services": [
      {
        "name": "ipsec/ikev2/standard"
      },
      {
        "name": "openvpn",
        "config": "client\ndev tun\nproto tcp\nremote 185.229.190.85 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
      },
      {
        "name": "http-proxy",
        "ports": [
          1543,
          23411
        ]
      },
      {
        "name": "ssl-proxy",
        "ports": [
          53235
        ]
      },
      {
        "name": "socks5-proxy",
        "ports": [
          86
        ]
      }
    ]
}
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). If you do not offer ssl-proxy service to your customesr, do not worry about this.

Active and Inactive

Nodes can be active or inactive. They will typically always be active. Currently, an inactive node does not mean the node is down or out-of-service. This flag is reserved for future use.

Get DNS Suffixes

GET /nodes/dns-suffixes/

Requires ROLE_RESELLER privileges.

Gets an array of DNS suffixes that can be appended to nodeNames in order to build a fully-qualified DNS name (FQDN). Nodes can be reached by their ipAddress or by FQDN DNS name (although ssl-proxy requires use of DNS name because certificates are signed against domain names, not IP addresses). We suggest using ipAddress when possible because some countries/ISPs block DNS names.

Resellers can request DNS name to be added to this list, in order to completely whitelist nodes.
curl example
$ curl 'https://domain.com/nodes/dns-suffixes/' -i -X GET \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (3)
1 Generates the HTTP Basic Authentication header. This can only be the reseller credentials.
2 Provided to you by FoxyProxy
3 There is no HTTP body
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[".somecompany.com", ".getfoxyproxy.org", ".foxyproxy.com"]

Get All Nodes

GET /nodes/?index=xxx&size=yyy

Requires ROLE_RESELLER privileges.

Get at most size nodes in the reseller pool, beginning at the specified zero-based index. Maximum value for size is 100. Nodes are sorted lexicographically by name.

The node can be reached by its ipAddress or by fully-qualified DNS name. Fully-qualified DNS names are calculated by concatenating nodeName with one of the values returned by from GET /nodes/dnsSuffixes/ (although ssl-proxy requires use of DNS name because certificates are signed against domain names, not IP addresses). We suggest using ipAddress when possible because some countries/ISPs block DNS names.

For brevity, this example only includes two nodes. Most resellers will have many more than that.
curl example
$ curl 'https://domain.com/nodes/?index=0&size=100' -i -X GET \ (1)
     --user milesDyson:skynet101 \ (2)
    -H 'X-DOMAIN: test-reseller-1' \ (3)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (4)
1 Minimum index is 0; max size is 100
2 Generates the HTTP Basic Authentication header. This can only be the reseller credentials.
3 Provided to you by FoxyProxy
4 There is no HTTP body
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

[
  {
    "active": true,
    "name": "test-node-de1", (1)
    "ipAddress": "123.41.54.2",
    "country": "Germany",
    "countryCode": "DE",
    "city": "Berlin",
    "services": [ (2)
      {
        "name": "ipsec/ikev2/standard"
      },
      {
        "name": "ipsec/cisco"
      },
      {
        "name": "ipsec/lt2p"
      },
      {
        "name": "openvpn",
        "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
      },
      {
        "name": "pptp"
      },
      {
        "name": "http-proxy",
        "ports": [
          6502,
          13301
        ]
      },
      {
        "name": "ssl-proxy",
        "ports": [
          999,
          1121
        ]
      },
      {
        "name": "socks5-proxy",
        "ports": [
          1080,
          36
        ]
      }
    ]
  },
  {
    "active": true,
    "name": "test-node-it1", (1)
    "ipAddress": "89.22.109.41",
    "country": "Milan",
    "countryCode": "IT",
    "city": "Italy",
    "services": [ (2)
      {
        "name": "ipsec/ikev2/standard"
      },
      {
        "name": "ipsec/cisco"
      },
      {
        "name": "ipsec/lt2p"
      },
      {
        "name": "openvpn",
        "config": "client\ndev tun\nproto tcp\nremote 89.22.109.41 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIC/jCCAegCAQAwgYoxgYcwDQYDVQQDDAZkZmRzZmcwGwYJKoZIhvcNAQkBEw5k\nc2ZnZ0BzZGZhLmNvbTAKBgNVBAsTA3NhZDAKBgNVBAoTA2FzZDAOBgNVBAkTB3Nk\ndmNhc3YwDQYDVQQHEwZzZHZhc2MwCQYDVQQIEwJUWDAMBgNVBBETBTc3MDk4MAkG\nA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi+KuwbmNk\nrlt9/mzpU3Wr+j/75rZJLEXj1LLacJ6dKmTick15pQiQ/neUsqElc8lE4ziX0lsp\nJIVstL9xpjYm0KG5BWiKffuAjoLlZEz29kAxd4+WiSGUdZy/jcdF/n8pLocQmeTz\nUcYRiQA2yXa/eBDT4Zv3N/oheemv0KQNnI/RI0F0Xmq7QBZ+SwOwBBH6x6UgPSrl\nIPxJ1uqjHnYtDSh3UJv3783MgSTTUs3KujTgDe2rb6sQ/zUo+RYoY9NdgmNnww4y\nvMu+InWaTmT9HPZiIIYVz2+7n6QLgMkSiBXJ16Qd20FOqTVaz/+wBm60mWR5KNXD\naREDLEzXI0L7AgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRLKS9Y\nJsHymtlmhQl988rFG2g+KzALBgkqhkiG9w0BAQsDggEBACeJm4OnGDOpSYRoG3NS\nyX4ehuK2PVnRIQGpuOrSCbZAmOMx85VgYZOG9bJyP+ejr01W4KEZdAvDEI8lKFsr\nztzpvWEmtDPijZJcJLONnDtQtw2cNgafi7ONWybi14oVskO+vAYe7nDfojpFkeKg\nEvRnTKsDCg4L2uZGL3Ko/rHiTD7e8kqn7zO/VqfaW+kDxBjy+3PCEppcnF4e5QWr\ncPCqZrOdLYvjzMtsj+QDZFkZElMHIcPUcM461cLuXo9pRegZ1zT/7QKAGmjBPg+z\nOSw30FqaXlrHqUK9Py2M/7eiN49cd7ije/+3HtBPslhYos/OaHyz/FY/iHz73ybm\nrVEHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHl\n-----END CERTIFICATE-----</ca>"
      },
      {
        "name": "pptp"
      },
      {
        "name": "http-proxy",
        "ports": [
          8903,
          12951
        ]
      },
      {
        "name": "ssl-proxy",
        "ports": [
          43,
          266
        ]
      },
      {
        "name": "socks5-proxy",
        "ports": [
          515
        ]
      }
    ]
  }
]
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.

Get Node By Name

GET /nodes/{nodeName}

Requires ROLE_RESELLER privileges.

Get the node with the specified nodeName in the reseller pool.

do not use a DNS name for nodeName. For example, if you want to GET testnode-nl01, do not use testnode-nl01.getfoxyproxy.org, testnode-nl01.foxyproxy.com, etc.

The node can be reached by its ipAddress or by fully-qualified DNS name. Fully-qualified DNS names are calculated by concatenating nodeName with one of the values returned by from GET /nodes/dnsSuffixes/ (although ssl-proxy requires use of DNS name because certificates are signed against domain names, not IP addresses). We suggest using ipAddress when possible because some countries/ISPs block DNS names.

curl example
$ curl 'https://domain.com/nodes/testnode-nl01/' -i -X GET \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (3)
1 Generates the HTTP Basic Authentication header. This can only be the reseller credentials.
2 Provided to you by FoxyProxy
3 There is no HTTP body
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{
  "active": true,
  "name": "test-node-de1", (1)
  "ipAddress": "123.41.54.2",
  "country": "Germany",
  "countryCode": "DE",
  "city": "Berlin",
  "services": [ (2)
    {
      "name": "ipsec/ikev2/standard"
    },
    {
      "name": "ipsec/cisco"
    },
    {
      "name": "ipsec/lt2p"
    },
    {
      "name": "openvpn",
      "config": "client\ndev tun\nproto tcp\nremote 123.41.54.1 443 tcp\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\ncomp-lzo\nverb 3\nauth-user-pass\n<ca>\n-----BEGIN CERTIFICATE-----\nMIIE7jCCA9agAwIBAgIJAKCGoU4jOKP3MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoT\nD0ZveHlQcm94eSwgSW5jLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9j\nYWxob3N0MRIwEAYDVQQpEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFk\nbWluQGdldGZveHlwcm94eS5vcmcwHhcNMTgwMTE3MDYzOTM1WhcNMjgwMTE1MDYz\nOTM1WjCBqjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRm\nb3JkMRgwFgYDVQQKEw9Gb3h5UHJveHksIEluYy4xEDAOBgNVBAsTB29wZW52cG4x\nEjAQBgNVBAMTCWxvY2FsaG9zdDESMBAGA1UEKRMJRm94eVByb3h5MSgwJgYJKoZI\nhvcNAQkBFhlzc2xhZG1pbkBnZXRmb3h5cHJveHkub3JnMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA7pPahdu5AX4iYFjgkjHFFKBdFC+j+VJ2BjcmpzfK\n4L0ahWfJRzw0GTH5mlgcj0b2vz0FhiHZZXEOF6qFtkBBycnHgep8EPjjqIzzbl28\nRuZ24DTmn/BokTPVBPIRd69JMg8W/Xt/DQYar4F0xpJkuWcHeJ39y3r68pxWrDqa\nwvmOv6WcMQHBj1rriHlA4KKqIRz279iOUWpU79HTCeM9l0NFUfuPMLPJuqacckak\n/GMad3ah9XL2vl63T3/O6PmGKkEz3L0W70XGeyXsFb8MEx6LSW3hyNC9S3Y3QKQQ\nqGNc+KBMwzl2sENE75gBDZzeIeaD1AlD2fycjyGx+tmvbwIDAQABo4IBEzCCAQ8w\nHQYDVR0OBBYEFCIs8LeB86HZFakNMWg7Dr4yg71pMIHfBgNVHSMEgdcwgdSAFCIs\n8LeB86HZFakNMWg7Dr4yg71poYGwpIGtMIGqMQswCQYDVQQGEwJVUzELMAkGA1UE\nCBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxGDAWBgNVBAoTD0ZveHlQcm94eSwgSW5j\nLjEQMA4GA1UECxMHb3BlbnZwbjESMBAGA1UEAxMJbG9jYWxob3N0MRIwEAYDVQQp\nEwlGb3h5UHJveHkxKDAmBgkqhkiG9w0BCQEWGXNzbGFkbWluQGdldGZveHlwcm94\neS5vcmeCCQCghqFOIzij9zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQC7U0PwUsJmmNHhHbTUMlsLAkd5DMrkoX1hQ55nEuSQNxHO8n75bQmBjlO2KqHr\nOOh1B6JBfTDdE4p55qAu1qfi7e9y+8QvIIYQCdp3o0QG84pYLJ7ftSknKKOZcfjI\nSxdK7+2UdN9ch+oOFrke9R1W3twIzlep9uyxwlnA5UeJ5Ax51+8eqFuKYkx0iIvY\n6D3GWWqDu80Pkpz/D5s9CkwLnCdFJIaHU6rNkoLYkv4g65P2IJJbhoDXTXStWrIO\nuKQxEWTrcjaVDyfNEyfjM6/Y7J9qMAjvVREkwrI0MNR94v6Rve/nV5GH581Vs//8\nJQqDdoW4E669ZSlrNgZk4E8r\n-----END CERTIFICATE-----</ca>"
    },
    {
      "name": "pptp"
    },
    {
      "name": "http-proxy",
      "ports": [
        6502,
        13301
      ]
    },
    {
      "name": "ssl-proxy",
      "ports": [
        999,
        1121
      ]
    },
    {
      "name": "socks5-proxy",
      "ports": [
        1080,
        36
      ]
    }
  ]
}
1 This is the nodename. It can be combined with any of the DNS suffixes from GET /nodes/dns-suffixes/ to create a fully-qualified DNS name. But you can always use ipAddress to connect to the server (except for the ssl-proxy service which requires a DNS name). We suggest using ipAddress when possible because some countries/ISPs block DNS names.
2 An array of VPN/proxy services supported by these nodes. In this example, both nodes support all of the same services.

Get Node Count

GET /nodes/count/

Requires ROLE_RESELLER privileges.

Gets the total number of nodes in the reseller pool.

curl example
$ curl 'https://domain.com/nodes/count/' -i -X GET \
     --user milesDyson:skynet101 \ (1)
    -H 'X-DOMAIN: test-reseller-1' \ (2)
    -H 'Accept: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8' \
    -H 'Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8'
    (3)
1 Generates the HTTP Basic Authentication header. This can only be the reseller credentials.
2 Provided to you by FoxyProxy
3 There is no HTTP body
HTTP response
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.foxyproxy.reseller.api.nonleased.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Content-Length: xxxx

{"count": 3}

Release Notes

Only release notes which change this API or this documentation are published. Therefore, some releases may not be documented here.

  • version 1.4.3, released 2018-04-17

    • Bugfix release. Preliminary support for copying accounts. No public changes yet.

  • version 1.4.2, released 2018-03-08

    • No public changes

  • version 1.4.1, released 2018-02-27

    • node objects now include node.services to explain the VPN and proxy protocols supported by a node, as well as configuration (for OpenVPN) and/or port information.

    • node.openVPNConfig is replaced by node.services.config where node.services.name is openvpn.

    • Added optional comment property to create/update/delete account endpoints. These will be retrievable from forthcoming GET /account/history/ endpoints.

    • Changed sort order of Get Accounts By Username and Get Accounts from user.uid to account.node.country

    • Added documentation section Availability

  • version 1.3.1, 2019-02-05

    • Fixed account creation bug affecting only secondary creates (whereby the account with a given username already exists); updated POST /accounts docs with extensive information about this functions behavior on subsequent calls with existing username

    • Nodes are referred to by a "short name", not full DNS name. This enables us to support multiple DNS names for each node, including custom DNS names for total whitelisting. The following changes occured to support this:

    • Added GET /nodes/dns-suffixes/ to get a list of DNS names for the current reseller

    • GET /nodes/?index=xxx&size=yyy returns a JSON with the property name instead of dnsName, and the value is a short name; e.g. "name":"testnode-de01" and not "name":"testnode-de01.getfoxyproxy.org" Concatenate the short name with the a value returned from /nodes/dns-suffixes/ to get fully qualified DNS names.

    • GET /nodes/{dnsName} changed to GET /nodes/{name}. It returns a JSON with the property name instead of dnsName, and the value is a short name; e.g. "name":"testnode-de01" and not "name":"testnode-de01.getfoxyproxy.org" Concatenate the short name with the a value returned from /nodes/dns-suffixes/ to get fully qualified DNS names.

    • PATCH /accounts/activate/{username} optional payload changed JSON property name from dnsNames to nodeNames. For example, {"dnsNames": ["testnode-nl01.getfoxyproxy.org", "testnode-uk01.getfoxyproxy.org"]} would now be {"nodeNames": ["testnode-nl01", "testnode-uk01"]}.

    • All references in documentation to dnsName or dnsNames changed to nodeName or nodeNames, except for the new method GET /nodes/dns-suffixes/

  • version 1.0.7, 2019-01-11

    • Fixed documentation examples for GET /nodes/{dnsName}/ and GET /nodes/ by removing extraneous nodes property

    • Ability to create new accounts in the inactive/deactivated state with the new active property in POST /accounts/

  • version 1.0, initial public release, 2018-11-27