FendVPN Docs
Search…
⌃K

Client API

Integrate VPN into any application

1. Overall API flow

Generally, API calls are divided by 3 groups:
  1. 1.
    Authorizing-related - provides authentication token to access further API calls.
  2. 2.
    Discovery-related - provides credentials to target VPN node.
  3. 3.
    Tunnel-related - manages actual wireguard tunnel
Please, take a look to next diagram to get actual requests sequence.

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 table below for fields description.
Field
Description
result
A predefined set of strings, identifying the type of happened error. See below all types.
error
More detailed error information.
details
Some extra information about error.

2.1. 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 entity is not found (for example, when ping request is done for outdated peer).
409
ENTRY_EXISTS
Can't create entry due to conflict. Can happen when 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
Request can't be done with provided authorization data.
507
INSUFFICIENT_STORAGE
Out of resoures to perform request.
503
SERVICE_UNAVAILABLE
Happens with request is done while service is shutting down or restarting.

3. Authorizer API

3.1. Authorize client

URL: https://thefend.com/api/client/signin
Method: POST
Authentication: None
Query string: None
Request body: JSON
Schema
Description
Example
OBJECT
{
project*: string
client_platform*: string
client_version*: string
device_id*: uuid
auth_type*: string
auth_info*: string
}
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
Fields, marked by * are required.
{
"project": "FendVPNTestProject",
"client_platform": "iphone",
"client_version": "1.0.1",
"device_id": "f7df7c7a-3569-401c-b612-f49b775bb19e",
"auth_type": "firebase",
"auth_info": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
Response body: JSON
Schema
Description
Example
OBJECT
{
access_token*: string
refresh_token: string
discovery_addresses: [uri]
}
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
Array of URLs for requesting locations and node credentials.
Fields, marked by * are required.
Notes:
  1. 1.
    If refresh_token is not specified, you should use authenticate again to get next token.
  2. 2.
    If discovery_addresses is not specified or empty, you should keep using same base URL (i.e. https://thefend.com) 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://thefend.com/api/client/locations
Method: GET
Authentication: Bearer
Query string: None
Request body: None
Response body: JSON
Schema
Description
Example
ARRAY
[
{
id*: string
name*: string
labels: {}
}
]
Response contains an array of locations. User should choose one before connect.
Name
Format
Description
id *
string
Location identifier.
name *
string
Location user-friendly name.
labels
array
Map of location labels, if specified.
Fields, marked by * are required.
[
{
id: "US",
name: "United States",
labels: { },
}
]

4.2. Get location nodes

URL: https://thefend.com/api/client/credentials
Method: GET
Authentication: Bearer
Query string: location=<LOCATION_ID>
Request body: None
Response body: JSON
Schema
Description
Example
ARRAY
[
{
id*: string
connection_addresses: [string]
}
]
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.
Name
Format
Description
id *
string
Server unique identifier.
connection_addresses
string
Array of servers URLs.
Fields, marked by * are required.
Notes:
  1. 1.
    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.thefend.com/api/client/connect
Method: POST
Authentication: Bearer
Query string: None
Request body: JSON
Schema
Description
Example
OBJECT
{
type*: enum
info_wireguard *: {
public_key: string
}
identifiers* {
installation_id: uuid
session_id: uuid
}
location: string
}
Name
Format
Description
type *
enum
Tunneling type. Only wireguard is supported now.
info_wireguard
object
Wireguard-specific connection information.
public_key *
string
Client wireguard public key.
identifiers
object
User-specific identifiers.
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.
Fields, marked by * are required.
{
"type": "wireguard",
"info_wireguard": {
"public_key": "ljs1lRH1YtZPlppYl1gQVX+JTNmTQsX57cIDf7oB6Qc="
},
"identifiers": {
"installation_id": "d1a1b2e2-d84b-4537-9a93-c4d3cd412598",
"session_id": "de9e0337-fb16-4669-b07d-9f261c329461"
}
}
Response body: JSON
Schema
Description
Example
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.
Fields, marked by * are required.
{
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
}
}

5.3. Heartbeat request.

URL: https://some-server-name.thefend.com/api/client/ping
Method: POST
Authentication: Bearer
Query string: None
Request body: JSON
Schema
Description
Example
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.
Fields, marked by * are required.
{
"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.thefend.com/api/client/disconnect
Method: POST
Authentication: Bearer
Query string: None
Request body: JSON
Schema
Description
Example
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.
Fields, marked by * are required.
{
"installation_id": "d1a1b2e2-d84b-4537-9a93-c4d3cd412598",
"session_id": "de9e0337-fb16-4669-b07d-9f261c329461"
}
Response body: None