For AI agents: markdown of this page — /docs-content-en/infra/deploy/port.md documentation index — /llms.txt
Set the application port
PATCH /v1/infra/servers/:id/port
Sets the TCP port to which the tunnel agent proxies incoming HTTPS requests from the subdomain. By default the tunnel goes to :3000 — this is the platform standard, and most applications should listen on exactly that. This endpoint is needed in rare cases: the application works on a different port for historical reasons, or you want 0 (auto-detect) so the agent finds the listening port itself. Ports 1–1023 are forbidden — these are system ports (SSH, HTTP, HTTPS, SQL), and using them would create a risk of redirecting traffic to service processes.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (UUID) | yes | BLACKHOLE server ID, status: running, blackholeStatus: CONNECTED |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
port |
number | yes | 0 (auto-detect) or 1024–65535. Ports 1–1023 are rejected with PORT_RESTRICTED |
Examples
curl — personal key
# Set port 8080
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/port \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"port": 8080}'
# Automatic detection
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/port \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"port": 0}'
curl — OAuth application
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/port \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"port": 8080}'
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/port`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ port: 8080 }),
}
)
const { data } = await res.json()
console.log(`Application port: ${data.port}`)
JavaScript — OAuth application
await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/port`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ port: 0 }),
}
)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.port |
number | The final port. With port: 0 it returns 3000 (the default value on auto-detect) |
data.mode |
string | manual (a specific port was set) or auto (port: 0) |
data.verified |
boolean | true — the platform confirmed (via probe) that the agent is already proxying to this port. false — the port was saved but routing isn't confirmed yet (see data.warning) |
data.warning |
string | Present only when verified: false: routing isn't confirmed and the app may briefly (up to ~30s) serve the Black Hole page until the auto-detector converges |
Response example
{
"success": true,
"data": { "port": 8080, "mode": "manual", "verified": true }
}
Error response example
400 — a system port is forbidden:
{
"success": false,
"error": {
"code": "PORT_RESTRICTED",
"message": "System ports (1-1023) are not allowed. Use port >= 1024 or 0 for auto-detect"
}
}
409 — the agent rejected the port change (fixed-port mode / outdated binary):
{
"success": false,
"error": {
"code": "PORT_NOT_APPLIED",
"message": "The server agent runs in fixed-port mode and cannot change its port at runtime. Repair the server (POST /v1/infra/servers/:id/repair) to switch the agent to port auto-detection, then retry.",
"agentError": "NO_SCANNER"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
port is not a number, outside the 0–65535 range |
| 400 | PORT_RESTRICTED |
A port in the 1–1023 range (system ports) |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not provided |
| 401 | INVALID_API_KEY |
Invalid or expired API key |
| 404 | NOT_FOUND |
The server is not BLACKHOLE + RUNNING, was deleted, or belongs to another API key |
| 409 | SERVER_NOT_READY |
The tunnel agent is not in the CONNECTED status |
| 409 | PORT_NOT_APPLIED |
The agent rejected the port change. agentError: NO_SCANNER — the server is in fixed-port mode (see below); a different agentError — the agent is outdated. Both are resolved by /repair |
| 429 | RATE_LIMITED |
The platform's overall request limit was exceeded |
| 502 | GATEWAY_ERROR |
The Gateway could not deliver the command to the agent |
Full list of common API errors — Errors.
Known specifics
- System ports (1–1023) are forbidden for a reason. SSH (22), HTTP (80), HTTPS (443), DNS (53), PostgreSQL (5432), MySQL (3306) — opening a tunnel on them would create a risk of redirecting external traffic to service processes inside the virtual machine.
- How
port: 0works. The agent scans/proc/net/tcpand/proc/net/tcp6, finds the process listening on an application port (≥1024), and proxies there. Useful for applications that pick a port dynamically at startup. - The value is preserved across agent restarts. The platform writes
localPortto the server's database — after/repairor a reboot the agent will use the same value. On a/deploywith an explicitportthe value is overwritten. port: 0is returned in the response as3000. This is not an error: "on auto-detect we return 3000 if nothing suitable was found". Check the actual listening port via/execwith the commandss -tlnp.- The platform confirms the port change (
data.verified). Afterset_portthe platform probes the agent and checks the tunnel actually proxies to the requested port.verified: true— routing is ready.verified: false+data.warning— the port was saved but the agent hasn't converged yet (the auto-detector picks it up within ~30s); if the app stays unavailable longer, run/repair.409 PORT_NOT_APPLIED— the agent did not accept the change at all: withagentError: NO_SCANNERthe server runs in fixed-port mode (run your app on the current port, or/repairto switch to auto-detection); with a differentagentErrorthe agent is outdated (/repairupdates it).
See also
- Full deploy — the
portfield in/deployalso configures the tunnel. - Tunnel metrics — whether there are HTTP connections and
lastRequestAt. - Run a command —
ss -tlnpto check the listening ports.