CallMeTechie
DE Login
Home Products Blog About Contact

Client API: Gateway-Companion Integration

⚙️ Advanced · Updated 1 month ago

API endpoints for communication between GateControl desktop clients (Windows, macOS, Linux) and the GateControl server.

All endpoints live under /api/v1/client/* and require authentication via an API token with scope peers or full-access.


Table of Contents


Authentication

The client authenticates via an API token. The token is created under Settings > API Tokens in the GateControl web interface and must have at least scope peers.

The token can be sent in three header variants:

Authorization: Bearer gc_your_token_here
X-API-Token: gc_your_token_here
X-API-Key: gc_your_token_here

Additionally, the client sends metadata headers:

X-Client-Version: 1.0.0
X-Client-Platform: windows

Creating a token (admin)

  1. Open the GateControl web interface
  2. Settings > API Tokens > Create Token
  3. Name: e.g. "Windows Client"
  4. Scope: peers (or full-access)
  5. Copy the token and enter it into the client

Connection flow

Client                                Server
  │                                      │
  │──── GET /client/ping ───────────────>│  1. Test connection
  │<──── { ok, version } ───────────────│
  │                                      │
  │──── POST /client/register ──────────>│  2. Register as peer
  │<──── { peerId, config, hash } ──────│     (peer is created automatically)
  │                                      │
  │     [ Client stores peerId ]         │
  │     [ Client writes WG config ]      │
  │     [ Client starts WG tunnel ]      │
  │                                      │
  │──── GET /client/config/check ───────>│  3. Periodically check for updates
  │<──── { updated: false } ────────────│     (every 300s, hash-based)
  │                                      │
  │──── POST /client/heartbeat ─────────>│  4. Send heartbeat
  │<──── { ok } ────────────────────────│     (periodically)
  │                                      │
  │──── POST /client/status ────────────>│  5. Report status events
  │<──── { ok } ────────────────────────│     (on connection state change)
  │                                      │

Endpoints

Ping

Checks reachability of the server and validity of the API token.

GET /api/v1/client/ping

Response:

{
  "ok": true,
  "version": "1.5.2",
  "timestamp": "2026-03-29T15:00:00.000Z"
}

Errors:

Status Meaning
401 Token invalid or missing
403 Token does not have peers scope

Register

Registers the client as a new WireGuard peer. The peer name is generated automatically from the hostname. On name collision a suffix is appended (e.g. DESKTOP-ABC, DESKTOP-ABC-1).

POST /api/v1/client/register

Request body:

{
  "hostname": "DESKTOP-ABC123",
  "platform": "win32 10.0.22631",
  "clientVersion": "1.0.0"
}
Field Type Required Description
hostname string yes Windows hostname (os.hostname())
platform string no Operating system info
clientVersion string no Client version

Response (201):

{
  "ok": true,
  "peerId": 5,
  "peerName": "DESKTOP-ABC123",
  "config": "[Interface]\nPrivateKey = ...\nAddress = 10.8.0.5/32\nDNS = 1.1.1.1,8.8.8.8\n\n[Peer]\nPublicKey = ...\nEndpoint = vpn.example.com:51820\nAllowedIPs = 0.0.0.0/0\nPersistentKeepalive = 25\n",
  "hash": "a1b2c3d4e5f6..."
}
Field Description
peerId Unique peer ID (store for all following requests!)
peerName Generated peer name
config Complete WireGuard client configuration
hash SHA-256 hash of the config (for update detection)

Errors:

Status Meaning
400 Hostname missing or invalid
403 License peer limit reached
409 No free IP addresses in the subnet

Note: The created peer appears in the GateControl web interface with the tag desktop-client and a description containing platform info.


Fetching config

Retrieves the current WireGuard configuration for the registered peer.

GET /api/v1/client/config?peerId=5
Parameter Type Required Description
peerId number yes Peer ID (from /register response)

Alternatively via header: X-Peer-Id: 5

Response:

{
  "ok": true,
  "config": "[Interface]\nPrivateKey = ...\n...",
  "hash": "a1b2c3d4e5f6...",
  "peerName": "DESKTOP-ABC123"
}

Checking for config updates

Checks whether the WireGuard configuration has changed since the last fetch (hash-based). This endpoint is called periodically by the client (default: every 300 seconds).

GET /api/v1/client/config/check?peerId=5&hash=a1b2c3d4e5f6...
Parameter Type Required Description
peerId number yes Peer ID
hash string no Last known config hash

Response (no change):

{
  "ok": true,
  "updated": false
}

Response (config changed):

{
  "ok": true,
  "updated": true,
  "config": "[Interface]\nPrivateKey = ...\n...",
  "hash": "f6e5d4c3b2a1..."
}

Behavior: If no hash parameter is sent, the server always returns the current config (updated: true).


Heartbeat

Periodically sends the client's current connection status to the server. Updates the peer's updated_at timestamp.

POST /api/v1/client/heartbeat

Request body:

{
  "peerId": 5,
  "connected": true,
  "rxBytes": 1048576,
  "txBytes": 524288,
  "uptime": 3600,
  "hostname": "DESKTOP-ABC123"
}
Field Type Required Description
peerId number yes Peer ID
connected boolean no VPN tunnel active?
rxBytes number no Received bytes
txBytes number no Transmitted bytes
uptime number no Connection duration in seconds
hostname string no Current hostname

Response:

{
  "ok": true
}

Reporting status

Reports one-off status events (e.g. connection established, disconnected, errors). Logged in the server's activity log.

POST /api/v1/client/status

Request body:

{
  "peerId": 5,
  "status": "connected",
  "timestamp": "2026-03-29T15:30:00.000Z"
}
Field Type Required Description
peerId number yes Peer ID
status string yes Status label
timestamp string no ISO 8601 timestamp

Typical status values:

Status Meaning
connected Tunnel established successfully
disconnected Tunnel disconnected
reconnecting Reconnect attempt in progress
error Connection error

Response:

{
  "ok": true
}

Error handling

All errors follow the standard format:

{
  "ok": false,
  "error": "Description of the error"
}
Status Meaning
400 Missing or invalid parameters
401 Authentication failed
403 Insufficient permissions or license limit
404 Peer not found
409 Resource conflict (e.g. no IPs available)
429 Rate limit exceeded (max. 100 requests/15 min)
500 Server error

Recommended client strategy

  • 401/403: Check the token, prompt re-entry if necessary
  • 404: Peer was deleted server-side, register again
  • 429: Observe Retry-After header, reduce requests
  • 5xx: Exponential backoff (2s, 3s, 4.5s, ... max 60s)

Examples

Complete setup flow with curl

TOKEN="gc_your_token_here"
SERVER="https://gate.example.com"

# 1. Ping
curl -s -H "X-API-Token: $TOKEN" "$SERVER/api/v1/client/ping"
# {"ok":true,"version":"1.5.2","timestamp":"..."}

# 2. Register
REGISTER=$(curl -s -X POST \
  -H "X-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hostname":"my-pc","platform":"linux","clientVersion":"1.0.0"}' \
  "$SERVER/api/v1/client/register")

PEER_ID=$(echo "$REGISTER" | jq -r '.peerId')
echo "Peer ID: $PEER_ID"

# 3. Fetch config
curl -s -H "X-API-Token: $TOKEN" \
  "$SERVER/api/v1/client/config?peerId=$PEER_ID" | jq -r '.config' > wg0.conf

# 4. Check for config updates
HASH=$(echo "$REGISTER" | jq -r '.hash')
curl -s -H "X-API-Token: $TOKEN" \
  "$SERVER/api/v1/client/config/check?peerId=$PEER_ID&hash=$HASH"
# {"ok":true,"updated":false}

# 5. Send heartbeat
curl -s -X POST \
  -H "X-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"peerId\":$PEER_ID,\"connected\":true,\"rxBytes\":0,\"txBytes\":0}" \
  "$SERVER/api/v1/client/heartbeat"

# 6. Report status
curl -s -X POST \
  -H "X-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"peerId\":$PEER_ID,\"status\":\"connected\"}" \
  "$SERVER/api/v1/client/status"

Windows client setup

  1. In the GateControl web interface: Settings > API Tokens > Create new token

    • Name: "Windows Client"
    • Scope: peers
    • Copy the token (displayed only once!)
  2. In the GateControl Windows client:

    • Open Settings
    • Enter the server URL (e.g. https://gate.example.com)
    • Enter the API token (starts with gc_)
    • Click Connect
  3. The client automatically registers, creates a peer and establishes the VPN tunnel.

Cookie Settings

We use cookies to improve your experience. Essential cookies are always active.

Privacy Policy
ESC
↑↓ navigate open esc close