For AI agents: markdown of this page — /docs-content-en/infra/access/mode.md documentation index — /llms.txt
Switch mode
PATCH /v1/infra/servers/:id/mode
Switches the server between BLACKHOLE mode (everything closed behind the firewall, access only via the HTTPS subdomain) and OPEN mode (direct access by IP, SSH on port 22 open). When switching to OPEN, the firewall is fully removed and an SSH password is generated. On the reverse switch, the firewall is restored and the password is deleted. Switching to OPEN is forbidden if the platform (the openModeEnabled flag) or the portal (the allowOpenMode policy) does not permit it.
OPEN disables Black Hole protection. The server becomes reachable from the internet by IP. All Deploy API endpoints (
/exec,/upload,/logs,/deploy) work only in BLACKHOLE mode — in OPEN they return an error.
Parameters
| Parameter | In | Type | Req. | Description |
|---|---|---|---|---|
id |
path | string (UUID) | yes | Server ID |
Request fields (body)
| Field | Type | Req. | Description |
|---|---|---|---|
mode |
string | yes | Target mode: OPEN or BLACKHOLE |
Examples
curl — personal key
# BLACKHOLE → OPEN
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/mode \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"mode": "OPEN"}'
# OPEN → BLACKHOLE (restore protection)
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/mode \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"mode": "BLACKHOLE"}'
curl — OAuth application
curl -X PATCH https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/mode \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "OPEN"}'
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/mode`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ mode: 'OPEN' }),
}
)
const { data } = await res.json()
if (data.sshPassword) console.log(`New SSH password: ${data.sshPassword}`)
JavaScript — OAuth application
await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/mode`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ mode: 'BLACKHOLE' }),
}
)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.mode |
string | New mode (OPEN or BLACKHOLE) |
data.ip |
string | null | Server IP (does not change on switching) |
data.sshPassword |
string | null | Generated SSH password. Returned only when switching to OPEN. When switching to BLACKHOLE — null |
Response example
BLACKHOLE → OPEN switch:
{
"success": true,
"data": {
"mode": "OPEN",
"ip": "178.154.230.106",
"sshPassword": "rT9xQ2mKaPzFHyB3"
}
}
OPEN → BLACKHOLE switch:
{
"success": true,
"data": {
"mode": "BLACKHOLE",
"ip": "178.154.230.106",
"sshPassword": null
}
}
Error response example
403 — switching to OPEN is forbidden by the portal policy:
{
"success": false,
"error": {
"code": "OPEN_MODE_NOT_ALLOWED",
"message": "OPEN mode is not allowed by portal policy",
"userMessage": "OPEN mode is not allowed by Bitrix24 account policy. An admin enables it in Settings → Creation. Meanwhile, use the Deploy API (exec/upload/logs)."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_MODE |
mode is not OPEN or BLACKHOLE |
| 400 | SAME_MODE |
The server is already in the requested mode |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not provided |
| 401 | INVALID_API_KEY |
Invalid or expired API key |
| 403 | OPEN_MODE_DISABLED |
OPEN mode is disabled on the platform (the openModeEnabled flag). Contact the platform administrator. The response carries error.userMessage — ready-made text in the user's language |
| 403 | OPEN_MODE_NOT_ALLOWED |
OPEN mode is forbidden by the portal policy (the allowOpenMode flag). Contact the Bitrix24 account administrator. The response carries error.userMessage. The exception is the second branch of the same code, with the message Portal context required — it arrives without userMessage |
| 404 | NOT_FOUND |
The server does not exist, was deleted, or belongs to another API key |
| 429 | RATE_LIMITED |
The platform's overall request limit was exceeded |
| 502 | PROVIDER_ERROR |
The cloud provider returned an error while changing the network configuration |
The full list of common API errors — Errors.
Known specifics
- OPEN resolution order (both levels must allow it): first the platform flag
openModeEnabled— the platform admin does not bypass this check either. Then the portal policyallowOpenMode— the platform admin bypasses it. Only if both allow it is switching to OPEN possible. - The IP does not change on switching. The cloud virtual machine stays the same — only the iptables rules and SSH configuration change.
- The tunnel (
blackholeStatus) is preserved in OPEN mode. The Black Hole agent keeps running, the HTTPS subdomain stays operational — the firewall simply no longer blocks external traffic. However, the Deploy API still refuses: it requires BLACKHOLE specifically. accessPolicyis not applied in OPEN. In OPEN, protection is built on SSH keys and iptables (which is removed); the HTTPS subdomain policy effectively does not work. On switching, theaccessPolicyvalue is preserved in the database — and starts taking effect again after returning to BLACKHOLE.
See also
- SSH credentials —
GET /v1/infra/servers/:id/ssh— get the password and command after switching to OPEN. - Access policy —
PATCH /v1/infra/servers/:id/access-policy— works only in BLACKHOLE. - Deploy API — available only in BLACKHOLE.
- Get server — check the current
mode.
SSH credentials
GET /v1/infra/servers/:id/ssh
Returns the SSH connection credentials. Full SSH access (with a password, private key, and public key) is returned only for servers in OPEN mode. For BLACKHOLE, all SSH fields are null: the server is closed behind the iptables firewall, and direct SSH is impossible. Instead of SSH, for BLACKHOLE use the Deploy API — /exec, /upload, /logs. Rate limit: up to 10 requests per minute per server.
Parameters
| Parameter | In | Type | Req. | Description |
|---|---|---|---|---|
id |
path | string (UUID) | yes | Server ID |
Examples
curl — personal key
curl -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/ssh
curl — OAuth application
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/ssh
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/ssh`,
{ headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const { data } = await res.json()
if (data.mode === 'OPEN') {
console.log('Command:', data.sshCommand)
console.log('Password:', data.sshPassword) // if it was issued
} else {
console.log(data.note) // BLACKHOLE — use the Deploy API
}
JavaScript — OAuth application
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/ssh`,
{
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
}
)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.mode |
string | OPEN or BLACKHOLE |
data.ip |
string | Public IP of the server |
data.sshDirect |
boolean | true for OPEN (SSH works by IP), false for BLACKHOLE (closed behind the firewall) |
data.sshUser |
string | null | SSH user: ubuntu or root. null for BLACKHOLE |
data.sshPort |
number | null | SSH port: 22. null for BLACKHOLE |
data.sshPassword |
string | null | Password. For BLACKHOLE always null. For OPEN — the password if the server generated one when switching to OPEN |
data.sshPrivateKey |
string | null | OpenSSH private key (ed25519). Returned for an OPEN server when the platform generated it |
data.sshPublicKey |
string | null | Public key (ed25519) — the matching public part for sshPrivateKey |
data.sshCommand |
string | null | Ready-to-copy command: ssh ubuntu@IP. For BLACKHOLE — null |
data.appUrl |
string | The application's HTTPS address (present only for BLACKHOLE, where SSH is unavailable) |
data.note |
string | Explanation for BLACKHOLE: "BLACKHOLE servers do not expose SSH. Use the Deploy API…" |
Response example
OPEN server:
{
"success": true,
"data": {
"mode": "OPEN",
"ip": "111.88.251.211",
"sshUser": "ubuntu",
"sshPort": 22,
"sshPassword": "Oi9owBO6zMbueGmM75J9hg",
"sshPrivateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmU…\n-----END OPENSSH PRIVATE KEY-----\n",
"sshPublicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM0JAP1EMGh0CkT7RkZ26pTSa4X1FsWXe61cB5Fiqqjz vibe-generated",
"sshCommand": "ssh ubuntu@111.88.251.211",
"sshDirect": true
}
}
BLACKHOLE server:
{
"success": true,
"data": {
"mode": "BLACKHOLE",
"ip": "93.77.184.167",
"sshDirect": false,
"sshPassword": null,
"sshPrivateKey": null,
"sshPublicKey": null,
"sshCommand": null,
"appUrl": "https://app-abc12345.vibecode.bitrix24.com",
"note": "BLACKHOLE servers do not expose SSH. Use the Deploy API (exec/upload/logs) instead."
}
}
Error response example
404 — the server does not exist:
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Server not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 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 does not exist, was deleted, or belongs to another API key |
| 429 | RATE_LIMITED |
The rate limit was exceeded (up to 10 requests per minute per server) or the platform's overall rate limit |
The full list of common API errors — Errors.
Known specifics
- Each BLACKHOLE → OPEN switch generates a new password. Old passwords (if any) become invalid. The same applies on the reverse cycle BLACKHOLE → OPEN → BLACKHOLE → OPEN: on every entry into OPEN, the platform generates a fresh
sshPassword. The password is also returned in the response toPATCH /mode— you can save it from there. sshPrivateKeyandsshPublicKeyare returned only for keys generated by the platform. If, when creating the server viaPOST /v1/infra/servers, you passed your ownsshPublicKey, the platform did not generate a private key — thesshPrivateKeyfield in the response will benull. Use your own private key on the client side.sshCommandis a ready "copy-paste" for AI agents and scripts. It is not a separate launch command — justssh ubuntu@IP. Authentication via password or key is a separate step on the SSH client side.- A separate limit — 10 requests per minute per server exists precisely because of the sensitivity of the returned data. The platform's overall limit is higher, but
/sshis throttled more strictly.
See also
- Switch mode —
PATCH /v1/infra/servers/:id/mode— switch to OPEN/BLACKHOLE. - Execute command —
POST /v1/infra/servers/:id/exec— the SSH equivalent for BLACKHOLE. - Upload file —
POST /v1/infra/servers/:id/upload— the scp equivalent for BLACKHOLE. - Access policy — who sees the application via HTTPS.