
## 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

```bash
# 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

```bash
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

```javascript
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

```javascript
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:

```json
{
  "success": true,
  "data": {
    "mode": "OPEN",
    "ip": "178.154.230.106",
    "sshPassword": "rT9xQ2mKaPzFHyB3"
  }
}
```

OPEN → BLACKHOLE switch:

```json
{
  "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:

```json
{
  "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](/docs/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 policy `allowOpenMode` — **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.
- **`accessPolicy` is 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, the `accessPolicy` value is preserved in the database — and starts taking effect again after returning to BLACKHOLE.

## See also

- [SSH credentials](./ssh.md) — `GET /v1/infra/servers/:id/ssh` — get the password and command after switching to OPEN.
- [Access policy](./access-policy.md) — `PATCH /v1/infra/servers/:id/access-policy` — works only in BLACKHOLE.
- [Deploy API](/docs/infra/deploy) — available only in BLACKHOLE.
- [Get server](/docs/infra/servers/get) — check the current `mode`.
