Interfaces
Each dongle is a network interface on your box. These endpoints show it and change how it gets its address.
Not available to reseller sub-users (403 forbidden). Changes need the owner or a team admin.
Addressing modes
Changes reach the box with its next heartbeat (~15 s). addressing.applied / addressing.error show what the box reported back.
Changing the dongle's own LAN subnet (HiLink) is only in the panel (proxy page → Interface → Advanced).
The interface object
{"proxy_id": 7, "iface": "enx0c5b8f279a64", "mac": "0c:5b:8f:27:9a:64", "hw_key": "path:1-1.1",
"usb_serial": null, "usb_path": "1-1.1", "usb_vendor": "12d1", "usb_product": "14db", "driver": "cdc_ether",
"up": true, "speed_mbps": null, "ipv4": "192.168.8.11/24", "src_ip": "192.168.8.11", "gateway": "192.168.8.1",
"route_table": 31007, "os_managed_by": "NetworkManager", "mtu": 1500,
"addressing": {"mode": "auto", "ip": "192.168.8.11", "prefix": 24, "gateway": "192.168.8.1", "mtu": null, "dns": null,
"reported_mode": "auto", "applied": true, "error": null},
"dhcp_lease": null,
"lan": {"gateway": "192.168.8.1", "prefix": 24, "source": "ssdp"}, "lan_mismatch": false,
"apn": {"supported": false, "value": null, "reported": null},
"data_connection": "connected", "data_connection_reason": null,
"warnings": {"shared_address": null, "possible_duplicate_of": null},
"status": "online", "last_seen_at": "2026-10-09T18:00:00+00:00"}
Top-level ipv4, src_ip, gateway, mtu are what the box reports; addressing is what you asked for.
Get
GET /proxies/{id}/interface
Ability: read
curl 'https://proxykite.com/api/v1/proxies/7/interface' \
-H "Authorization: Bearer $HYP_TOKEN" \
-H 'Accept: application/json'
import os
import requests
r = requests.get(
"https://proxykite.com/api/v1/proxies/7/interface",
headers={"Authorization": f"Bearer {os.environ['HYP_TOKEN']}", "Accept": "application/json"},
timeout=30,
)
print(r.status_code, r.json())
const res = await fetch('https://proxykite.com/api/v1/proxies/7/interface', {
headers: {
Authorization: `Bearer ${process.env.HYP_TOKEN}`,
Accept: 'application/json',
},
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
<?php
$ch = curl_init('https://proxykite.com/api/v1/proxies/7/interface');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HYP_TOKEN'),
'Accept: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($status, json_decode($body, true));
Response 200: {"data": <interface>}
Change addressing
PATCH /proxies/{id}/interface
Ability: manage · Who: owner or team admin.
curl -X PATCH 'https://proxykite.com/api/v1/proxies/7/interface' \
-H "Authorization: Bearer $HYP_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"mode":"static","ip":"192.168.8.20","prefix":24,"gateway":"192.168.8.1"}'
import os
import requests
r = requests.patch(
"https://proxykite.com/api/v1/proxies/7/interface",
headers={"Authorization": f"Bearer {os.environ['HYP_TOKEN']}", "Accept": "application/json"},
json={"mode": "static", "ip": "192.168.8.20", "prefix": 24, "gateway": "192.168.8.1"},
timeout=30,
)
print(r.status_code, r.json())
const res = await fetch('https://proxykite.com/api/v1/proxies/7/interface', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.HYP_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({"mode":"static","ip":"192.168.8.20","prefix":24,"gateway":"192.168.8.1"}),
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
<?php
$ch = curl_init('https://proxykite.com/api/v1/proxies/7/interface');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HYP_TOKEN'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{"mode":"static","ip":"192.168.8.20","prefix":24,"gateway":"192.168.8.1"}',
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($status, json_decode($body, true));
Response 200: {"data": <interface>} · 422 validation_failed for bad or clashing addresses.
Reset the link
POST /proxies/{id}/interface/reset
Ability: manage · Who: owner or team admin.
Queues a link down/up and re-applies the settings on the box. Not available in system mode (422, fields.mode).
curl -X POST 'https://proxykite.com/api/v1/proxies/7/interface/reset' \
-H "Authorization: Bearer $HYP_TOKEN" \
-H 'Accept: application/json'
import os
import requests
r = requests.post(
"https://proxykite.com/api/v1/proxies/7/interface/reset",
headers={"Authorization": f"Bearer {os.environ['HYP_TOKEN']}", "Accept": "application/json"},
timeout=30,
)
print(r.status_code, r.json())
const res = await fetch('https://proxykite.com/api/v1/proxies/7/interface/reset', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.HYP_TOKEN}`,
Accept: 'application/json',
},
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
<?php
$ch = curl_init('https://proxykite.com/api/v1/proxies/7/interface/reset');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HYP_TOKEN'),
'Accept: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($status, json_decode($body, true));
Response 202
{"data": {"id": 41, "type": "reset_iface", "mac": "0c:5b:8f:27:9a:64", "hw_key": "path:1-1.1",
"status": "pending", "error": null, "created_at": "2026-10-09T18:00:00+00:00"}}
The box picks the action up with its next heartbeat; its progress shows in GET /nodes/{id}/interfaces →
pending_actions while it is pending.
Set the APN
PATCH /proxies/{id}/interface/apn
Ability: manage · Who: owner or team admin.
The APN the box uses to bring the modem's data connection up. Only for devices with the data_connect
capability (USB modems, agent ≥ 1.6.0; apn.supported is true);
other devices answer 409 unsupported.
curl -X PATCH 'https://proxykite.com/api/v1/proxies/7/interface/apn' \
-H "Authorization: Bearer $HYP_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"apn":"internet"}'
import os
import requests
r = requests.patch(
"https://proxykite.com/api/v1/proxies/7/interface/apn",
headers={"Authorization": f"Bearer {os.environ['HYP_TOKEN']}", "Accept": "application/json"},
json={"apn": "internet"},
timeout=30,
)
print(r.status_code, r.json())
const res = await fetch('https://proxykite.com/api/v1/proxies/7/interface/apn', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.HYP_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({"apn":"internet"}),
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
<?php
$ch = curl_init('https://proxykite.com/api/v1/proxies/7/interface/apn');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HYP_TOKEN'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{"apn":"internet"}',
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($status, json_decode($body, true));
Response 200: {"data": <interface>} · 409 unsupported without data_connect · 422 validation_failed for a bad APN.