Skip to content

VPNHouse Client API

1. Overall API Flow

Generally, API calls are divided by 3 groups:

  1. Authorizing-related - provides authentication token to access further API calls
  2. Discovery-related - provides credentials to target VPN nodes
  3. Tunnel-related - manages actual wireguard tunnel

Please, take a look at the next diagram to get the actual sequence of requests.

2. Errors

2.1. Generic Description

All errors are returned with meaningful HTTP error code and JSON body with more detailed information. For example, syntax error will return HTTP 400 error with next body:

{
    result: "INVALID_ARGUMENT",
    error: "Invalid request",
    details: "invalid character '\\n' in string literal"
}

Check the table below for the field description.

Field Description
result A predefined set of strings, identifying the type of error. See below all types.
error More detailed error information.
details Some extra information about errors.

2.2. List of Errors

HTTP code Result code Description
500 INTERNAL_ERROR Any unexpected behavior of backend components.
400 INVALID_ARGUMENT Invalid request data, like syntax or type errors.
404 NOT_FOUND Managed entities are not found (for example, when a ping request is done for outdated peers).
409 ENTRY_EXISTS Can't create entry due to conflict. Can happen when the wireguard key is already used.
500 STORAGE_ERROR Internal storage failure.
500 TUNNEL_ERROR Tunnel management failure.
401 UNAUTHORIZED Request requires authorization.
401 AUTH_FAILED Requests can't be done with provided authorization data.
507 INSUFFICIENT_STORAGE Out of resources to perform requests.
503 SERVICE_UNAVAILABLE Happens when a request is made while the service is shutting down or restarting.

3. Authorizer API

3.1. Authorize client

URL: https://api.vpnhouse.net/api/client/signin

Method: POST

Authentication: None

Query string: None

Request body: JSON

Fields, marked with * are mandatory.

OBJECT 

{
  project*: string
  client_platform*: string
  client_version*: string
  device_id*: uuid
  auth_type*: string
  auth_info*: string
}

Fields, marked with * are mandatory.

Name Format Description
project * string Name of the project
client_platform * string Client platform (i.e. ios, android, etc.)
client_version * string Version of client application release (i.e. 1.2.3)
device_id * string Device ID in UUID format
auth_type * string Authentication scheme
auth_info * string Authentication information
{
  "project": "Project",
  "client_platform": "iphone",
  "client_version": "1.0.1",
  "device_id": "f7df7c7a-3569-401c-b612-f49b775bb19e",
  "auth_type": "firebase",
  "auth_info": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
{
  "project": "Project",
  "client_platform": "iphone",
  "client_version": "1.0.1",
  "device_id": "f7df7c7a-3569-401c-b612-f49b775bb19e",
  "auth_type": "anonymous",
  "auth_info": "be2757b5-f8ba-49ea-9c7d-dcce2d1390f2"
}

Response body: JSON

Fields, marked with * are mandatory.

OBJECT

{
    access_token*: string
    refresh_token: string
    discovery_addresses: [uri]
}

Fields, marked with * are mandatory.

Name Format Description
access_token * string JWT token, used for all further operations with backend
refresh_token string JWT token, used to get new access token.
discovery_addresses array[uri] Array of URLs for requesting locations and node credentials.

If refresh_token is not specified, you should authenticate again to get next token.

If discovery_addresses is not specified or empty, you should keep using same base URL (i.e. https://api.vpnhouse.net) for discovery requests.

{
    access_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjBmNmQwZGFiLWU0NzgtNGQ1Ni1hZGJhLTU5M2ZhYmE4ZTRhYiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ2cG4tbm9kZSIsImV4cCI6MTYyNDk0OTk0NywianRpIjoiNTUxNzYyODQtZDdkZS0xMWViLWE2NDUtMDI0MmFjMTIwMDAyIiwiaWF0IjoxNjI0ODYzNTQ3LCJpc3MiOiJUZXN0UHJvamVjdC1BdXRoLTEtMiIsIm5iZiI6MTYyNDg2MzU0Nywic3ViIjoiRmVuZFZQTlRlc3RQcm9qZWN0L2ZpcmViYXNlL0pvaG5Eb2UifQ.REIfc3DB4e4pU7GyNU7vmJfsJBDu-0PLghV06KIdEM0Vhg4jVFA4MzgRU_j151PrAalSrpj0gLJGW8qZfqSLyDshRQCjgKYEt_X5PmNVkFmAjUz6hwCBJ8tMRxfhG2vcG1WZF80aTLLx6LQ0NwGT6hfAYEemzAecVwvnTuE1BQow3c1T71uZSByLDP1WAa0ZYnNZjceOGeikSXK5RtHogSyZkud7zfi_dKhDzW8Pgd_06HYEmexogv3LMpbJ0NY0nrRnxqPlJ1-uqQ6OIktQe1RvLe7BTGBthp_wrAv3Z9YdGSzJrlJhr1hg6qTzzdo0UHdvCpMeIun8bpr7OWVEIg",
    refresh_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjBmNmQwZGFiLWU0NzgtNGQ1Ni1hZGJhLTU5M2ZhYmE4ZTRhYiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZWZyZXNoIiwiZXhwIjoxNjMwMTMzOTQ3LCJqdGkiOiI1NTE3NjI4NC1kN2RlLTExZWItYTY0NS0wMjQyYWMxMjAwMDIiLCJpYXQiOjE2MjQ4NjM1NDcsImlzcyI6IlRlc3RQcm9qZWN0LUF1dGgtMS0yIiwibmJmIjoxNjI0ODYzNTQ3LCJzdWIiOiJGZW5kVlBOVGVzdFByb2plY3QvZmlyZWJhc2UvSm9obkRvZSJ9.GbhbrSxLcoj7yJFQnh1Pq2_3OXMnffihRaRyOsHay8RLyZzwHTpHN_uEcT-5z7l_kbrcWWMuswChrnt6zYuzzMa_qPFXpSIwkf3xXrFOr4Og-wLQqsy6Uh7-hJB546mMt-bT7tCFXZbNRtCm_lzIW6mPAcIJtofJsqSPaFL-xWrJEl0m4vRNV4NusGwlCuE7uvjQPLUF5gS98QLLWNWyHipVWxjSEK57I0ngrsOU7b4jETHxtgYYQ_O2S5GoOUe0YrwYFkrKP1LB3eE_aAw-toOJSP6eVm_Y345MBVJj8NcGa3Kbdm5SzZhHs2P-ZoKc8Yp2FdiFPyCq6VDmQ2PyXw",
    discovery_addresses: [
        "https://discovery.project.io/api/client/locations"
    ]
}

4. Discovery API

4.1. List locations

URL: https://api.vpnhouse.net/api/client/locations

Method: GET

Authentication: Bearer

Query string: None

Request body: None

Response body: JSON

Fields, marked with * are mandatory.

ARRAY

[
    {
        id*: string
        name*: string
        labels: {}
    }
]

Fields, marked with * are mandatory.

Name Format Description
id * string Location identifier.
name * string Location user-friendly name.
labels array Map of location labels, if specified.
[
    {
        id: "US",
        name: "United States",
        labels: { },
    }
]

4.2. Get location nodes

URL: https://api.vpnhouse.net/api/client/credentials

Method: GET

Authentication: Bearer

Query string: location=<LOCATION_ID>

Request body: None

Response body: JSON

Fields, marked with * are mandatory.

ARRAY

[
    {
        id*: string
        connection_addresses: [string]
    }
]

Fields, marked with * are mandatory.

Name Format Description
id * string Server unique identifier.
connection_addresses string Array of servers URLs.

Response contains an array of a server nodes in order to try them. I.e. application should always start from first entry in array, if it's failed - go to second, etc.

If connection_addresses is not specified or empty, you should keep using same base URL to establish tunnel connections. This can happen when you use demo backend.

[
    {
        id: "US",
        name: "United States",
        labels: { },
    }
]

5. Tunneling API

5.1. Initiate connection.

URL: https://some-server-name.vpnhouse.net/api/client/connect

Method: POST

Authentication: Bearer

Query string: None

Request body: JSON

Fields, marked with * are mandatory.

OBJECT 

{
    info_wireguard*: {
        public_key: string
    }

    identifiers* {
        installation_id: uuid
        session_id: uuid
    }

    location: string
}

Fields, marked with * are mandatory.

Name Format Description
info_wireguard object Wireguard-specific connection information.
public_key * string Client wireguard public key.
installation_id * uuid Application installation ID. Generated during installation or first application startup.
session_id * uuid Session ID. Generated every time when user starts connection.
location string Location ID.
{
  "info_wireguard": {
    "public_key": "+NK8yiGfvGOoAFVFii8bU6JCqd4j5dSpMppfIeJDtx0="
  },
  "identifiers": {
    "installation_id": "d1a1b2e2-d84b-4537-9a93-c4d3cd412598",
    "session_id": "de9e0337-fb16-4669-b07d-9f261c329461"
  },
  "location": "US"
}

Response body: JSON

OBJECT

{
    info_wireguard: {
        server_public_key*: string
        server_ipv4*: ipv4
        server_port*: integer
        tunnel_ipv4*: ipv4
        keepalive*: integer
        allowed_ips*: [string]
        dns*: [ipv4]
        ping_interval*: integer
    }
}
Name Format Description
info_wireguard object Wireguard-specific connection information.
server_public_key string Server wireguard public key.
server_ipv4 ipv4 Server ipv4.
server_port integer Server port.
tunnel_ipv4 ipv4 Client in-tunnel ipv4 address.
keepalive integer Wireguard keepalive interval. Zero means no keepalive.
allowed_ips array[cidr] List of allowed IPs in terms of wireguard configuration.
dns array[ipv4] List of DNS addresses to use.
ping_interval integer Interval to do a heartbeat request.
{
    info_wireguard: {
        server_public_key: "b0o7b8vXx9EH3uLJucOJUed0slvSppv7RCmC8jXRr1o=",
        server_ipv4: "1.2.3.4",
        server_port: 3000,
        tunnel_ipv4: "192.168.2.2",
        keepalive: 60,
        allowed_ips: [
            "0.0.0.0/0"
        ],
        dns: [
            "198.51.100.42"
        ],
        ping_interval: 60
    }
}

Wireguard config pattern

[Interface]
Address = $tunnel_ipv4/32
DNS = $dns_comma_separated_list
PrivateKey = $private_key

[Peer]
PublicKey = $server_public_key
AllowedIPs = $allowed_ips_comma_separated_list
Endpoint = $server_ipv4:$server_port

Wireguard config example

[Interface]
Address = 192.168.2.2/32
DNS = 198.51.100.42
PrivateKey = ADKch0tZqNb7iH/Wupl4STtCAJNI0jS5JCHr9Rg9WUk=

[Peer]
PublicKey = b0o7b8vXx9EH3uLJucOJUed0slvSppv7RCmC8jXRr1o=
AllowedIPs = 0.0.0.0/0
Endpoint = 1.2.3.4:3000

5.2. Heartbeat request.

URL: https://some-server-name.vpnhouse.net/api/client/ping

Method: POST

Authentication: Bearer

Query string: None

Request body: JSON

OBJECT 

{
    installation_id: uuid
    session_id: uuid
}
Name Format Description
installation_id * uuid Application installation ID. Generated during installation or first application startup.
session_id * uuid Session ID. Generated every time when user starts connection.
{
  "installation_id": "d1a1b2e2-d84b-4537-9a93-c4d3cd412598",
  "session_id": "de9e0337-fb16-4669-b07d-9f261c329461"
}

Response body: None

5.3. Drop connection.

URL: https://some-server-name.vpnhouse.net/api/client/disconnect

Method: POST

Authentication: Bearer

Query string: None

Request body: JSON

OBJECT 

{
    installation_id: uuid
    session_id: uuid
}
Name Format Description
installation_id * uuid Application installation ID. Generated during installation or first application startup.
session_id * uuid Session ID. Generated every time when user starts connection.
{
  "installation_id": "d1a1b2e2-d84b-4537-9a93-c4d3cd412598",
  "session_id": "de9e0337-fb16-4669-b07d-9f261c329461"
}

Response body: None