API: tunnels
List, create and delete HF Tunnel links of a hosting account, and get what a tunnel client needs to connect.
HF Tunnel gives a website or app running on your own computer a public address on the server, such as
https://myapp.port.yourdomain.com. These endpoints manage one hosting account's tunnels. The HF Server desktop app
uses them for Share → your HF Panel server; your own scripts can too.
With a customer's token they work on the token's own account. With an administrator's or reseller's token, add
?account=<username>.
A=https://api.yourdomain.com:2087/v1
H="Authorization: Bearer hf_xxx"
Note: tunnels work only when the administrator has set up HF Tunnel on the server. Until then,
GET /v1/tunnelsanswers"enabled": falseand creating a tunnel answers 422 "Tunnels are not switched on on this server."
GET /v1/tunnels
The account's tunnels. Who: per account; any token.
curl -s -H "$H" "$A/tunnels?account=sarahbakes"
{
"ok": true,
"data": {
"enabled": true,
"domain": "port.yourdomain.com",
"limit": 3,
"server_online": true,
"tunnels": [
{
"name": "myapp",
"url": "https://myapp.port.yourdomain.com",
"port": 3000,
"online": false,
"created_at": "2026-10-20 16:45:00"
}
]
}
}
| Field | What it is |
|---|---|
enabled |
whether HF Tunnel is set up on the server. When false, data is {"enabled": false, "tunnels": []} |
domain |
the tunnel domain; every tunnel's address is <name>.<domain> |
limit |
how many tunnels one account may have |
server_online |
whether the tunnel server is running |
tunnels |
the account's tunnels |
POST /v1/tunnels
Creates a tunnel. Who: per account, Read & change token. Answers 201.
| Field | Required | What it does |
|---|---|---|
name |
yes | the first part of the address: lower-case letters, numbers and -, up to 32 characters, not starting or ending with - |
port |
no | the local port to forward to, 1–65535; default 80 |
curl -s -H "$H" -H 'Content-Type: application/json' "$A/tunnels?account=sarahbakes" \
-d '{"name":"myapp","port":3000}'
{
"ok": true,
"data": {
"name": "myapp",
"url": "https://myapp.port.yourdomain.com",
"port": 3000,
"online": false,
"created_at": "2026-10-25 09:30:12"
}
}
| Status | error |
|---|---|
| 422 | myapp is taken — try another name. |
| 422 | You can have 3 tunnels — delete one first. |
| 422 | Port: 1–65535. |
Some names are reserved (such as www, mail, panel and admin) and answer 422 with the reason.
GET /v1/tunnels/{name}/client
What a tunnel client needs to connect this tunnel. Because the answer contains the tunnel's secret key, it needs a Read & change token even though it only reads. Who: per account, Read & change token.
curl -s -H "$H" "$A/tunnels/myapp/client?account=sarahbakes"
{
"ok": true,
"data": {
"name": "myapp",
"url": "https://myapp.port.yourdomain.com",
"server_addr": "panel.yourdomain.com",
"server_port": 7000,
"auth_token": "9a1e…",
"user": "sarahbakes",
"key": "5c0d…",
"client_download": "https://api.yourdomain.com:2087/v1/tunnel-get?t=5c0d…&os=bin&arch=",
"arches": [
"linux_amd64",
"linux_arm64",
"darwin_amd64",
"darwin_arm64",
"windows_amd64",
"windows_arm64"
]
}
}
| Field | What it is |
|---|---|
server_addr, server_port |
the tunnel server to connect to (port 7000) |
auth_token, user, key |
the credentials the tunnel client sends |
client_download |
where to download the tunnel client; add one of arches to the end |
tls_ca, tls_server_name |
present when the tunnel server uses the server's own certificate authority |
An unknown tunnel answers 404 "No such tunnel on this account."
Warning: anyone with
keycan serve content on the tunnel's address. Keep it as secret as a password.
DELETE /v1/tunnels/{name}
Deletes a tunnel. Its address stops working at once. Who: per account, Read & change token.
curl -s -H "$H" -X DELETE "$A/tunnels/myapp?account=sarahbakes"
{
"ok": true,
"data": {
"deleted": "myapp"
}
}