
## List of runtimes

`GET /v1/infra/runtimes`

Returns the IDs of ready-made runtimes to pass into [`POST /v1/infra/servers/:id/deploy`](./deploy.md) (the `runtime` parameter). The `runtime` parameter is optional: if the stack you need is in the list, pass its ID and the platform will install the packages automatically. If not, a deploy without `runtime` on a dedicated virtual machine still works fully — install the software you need via `preStart` in the request body. For a Galaxy application `runtime` is required and `preStart` does not apply. On [`POST /v1/infra/servers`](/docs/infra/servers/create) a runtime without `source` has NOT been accepted since 2026-04-25 — see `RUNTIME_PARAM_REMOVED`. When a Galaxy application is created in one step, `runtime` is passed together with `source`; `start` is also required unless the runtime is `static`, where it is optional and ignored. Each runtime is a set of system packages (nodejs, python, nginx, databases) installed on the server. The estimated installation time is 2–4 minutes for the basic ones, up to 4+ minutes for combinations with several packages.

## Examples

### curl — personal key

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.com/v1/infra/runtimes
```

### curl — OAuth application

```bash
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.com/v1/infra/runtimes
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/infra/runtimes', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data: runtimes } = await res.json()
runtimes.forEach(r => console.log(`${r.id}: ${r.name} (${r.estimatedSetupTime}s)`))
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/infra/runtimes', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data` | array | Array of runtimes |
| `data[].id` | string | The runtime ID, passed as `runtime` on deploy (`POST /v1/infra/servers/:id/deploy`) |
| `data[].name` | string | Display name for the user |
| `data[].packages` | array\<string\> | List of packages installed on a dedicated virtual machine (for reference) |
| `data[].estimatedSetupTime` | number | Estimated installation time in seconds |
| `data[].supportedPlacements` | array\<string\> | Where the runtime is available: `["standalone"]` — dedicated virtual machine only, `["standalone","galaxy"]` — Galaxy too. Check this field before a Galaxy deploy: a runtime with a database cannot be installed there |
| `data[].deprecated` | boolean | `true` — the language line is no longer supported: deploys still work, but use the runtime in `replacement` for a new app |
| `data[].replacement` | string \| null | ID of the runtime that replaces a deprecated one with the same package set, for example `node24-pg` instead of `node20-pg`. `null` for a supported runtime |

## Response example

```json
{
  "success": true,
  "data": [
    {
      "id": "node24",
      "name": "Node.js 24",
      "packages": ["nodejs-24", "npm", "pm2"],
      "estimatedSetupTime": 150,
      "supportedPlacements": ["standalone", "galaxy"],
      "deprecated": false,
      "replacement": null
    },
    {
      "id": "node24-pg",
      "name": "Node.js 24 + PostgreSQL",
      "packages": ["nodejs-24", "npm", "pm2", "postgresql-16"],
      "estimatedSetupTime": 210,
      "supportedPlacements": ["standalone"],
      "deprecated": false,
      "replacement": null
    },
    {
      "id": "node20",
      "name": "Node.js 20",
      "packages": ["nodejs-20", "npm", "pm2"],
      "estimatedSetupTime": 120,
      "supportedPlacements": ["standalone", "galaxy"],
      "deprecated": true,
      "replacement": "node24"
    }
  ]
}
```

## Error response example

401 — no API key provided:

```json
{
  "success": false,
  "error": {
    "code": "MISSING_API_KEY",
    "message": "API key required. Pass via X-Api-Key header."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not provided |
| 401 | `INVALID_API_KEY` | The key is not recognized — no such key exists on the platform |
| 429 | `RATE_LIMITED` | The platform's overall request limit was exceeded |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **For a new Node.js app, use `node24` or one of its variants.** Node.js 20 reached end of life on 2026-04-30 and no longer receives security fixes. The `node20*` runtimes stay in the list for apps already deployed on them and are marked `deprecated: true` with the successor in `replacement`. Moving to `node24` is a new deploy with `runtime: "node24"`. npm modules with C/C++ code are rebuilt for Node.js 24 during that deploy, so do not ship a `node_modules` directory built under Node.js 20 in the archive.
- **Deploying `node20*` to a dedicated virtual machine can overwrite the NodeSource `apt` settings made on the machine by hand.** When the `node` command on the machine does not report version 20 — on the runtime's first install, or when moving from `node24*` back to `node20*` — the platform installs Node.js 20 with the NodeSource repository installer. The installer replaces the `/usr/share/keyrings/nodesource.gpg` key and rewrites the `/etc/apt/preferences.d/nodejs` and `/etc/apt/preferences.d/nsolid` files in full, leaving priority 600 for packages from `deb.nodesource.com`. The platform neither saves nor restores their previous contents. If the NodeSource install fails and Node.js 20 comes from the archive instead, these files may still end up overwritten or deleted. Keep a copy of your own `nodejs` version pin or key and put it back after the deploy. `node20*` deploys leave these files alone while the `node` command reports version 20 and `npm` works, and the `node24*` installer never touches them.
- **The start command depends on the runtime — pass it in the deploy `start` field, except for `static`.** For `static`, the field is optional and ignored: the platform starts nginx itself. Other runtimes use these commands on a dedicated virtual machine: `node24*` and `node20*` — `node`, `python311*` — `python3.11`, `python312*` — `python`, and `php83*` — `php8.3`. The `python3.11` and `python` commands work in Galaxy too, so such a `start` fits both placement models. A machine with `python311*` has no `python` command, and `python3` stays the Ubuntu 24.04 system interpreter — that is version 3.12. The `python311*` runtime binds `pip` to 3.11, so `pip install` in the `install` field puts dependencies into the same interpreter that runs the app.
- **With `python312*`, the app's packages live in a separate platform Python environment.** On a dedicated virtual machine Python 3.12 comes from the Ubuntu 24.04 archive, and the `python`, `pip` and `pip3` commands run in an environment the platform creates next to it and keeps between deploys. So `pip install -r requirements.txt` in the `install` field and `python app.py` in the `start` field see the same packages. The `python3` and `python3.12` commands stay the Ubuntu system interpreter without the app's packages: a `start` like `python3 app.py` works in Galaxy, but on a dedicated machine the app stops at its first package import. A package's console command, such as `uvicorn` or `gunicorn`, is callable by name after `pip install` if the machine has no command with that name yet. If the machine previously ran `python311*`, the earlier runtime's command of the same name stays in place — run it as a module: `python -m uvicorn main:app`. Pinned `numpy` versions below 1.26 and `pandas` versions below 2.1 do not build under Python 3.12 — raise them in `requirements.txt`.
- **The `pm2` package in a runtime's list is a tool installed on the machine, not a way to start the application.** The `node24` and `node20` runtimes and their variants install `pm2` alongside Node.js, but the `start` field requires a command that stays in the foreground and holds the listener itself. A command such as `pm2 start server.js --name app && pm2 save` launches a daemon and exits, and once it exits the platform stops the application service too. The full rule, both outcomes of such a command and what tells them apart in the deploy result — [Full deploy](./deploy.md), "Known specifics".
- **The `php83` and `php83-mysql` runtimes, and the MySQL variants (`node24-mysql`, `node24-mysql-redis`, `node20-mysql`, `node20-mysql-redis`, `python311-mysql`, `python312-mysql`), need `"hardening": "off"`.** After installation MySQL allows only the administrator to connect over the local socket, and PHP-FPM runs as a separate system service — under an unprivileged account the app cannot reach the database. The platform restores the previous mode on its own, but the attempt and its health check cost time on every deploy. Pass `"hardening": "off"` in the deploy body to skip it. Apps that reach MySQL over TCP with a password do not need this.
- **Combo runtimes run on a dedicated virtual machine only.** The `-pg` / `-mysql` / `-redis` / `-rag` suffixes describe the dedicated-machine template: there, PostgreSQL / MySQL / Redis really is installed alongside the language. A Galaxy app is a single language container on a shared host — no database is started there and no connection variables (`DATABASE_URL`, `PG*`, etc.) are injected, so deploying such a runtime into Galaxy is **refused**: a `400` with code `GALAXY_RUNTIME_DB_UNSUPPORTED`, a `details.suggestedRuntime` field (the language replacement — `node24` instead of `node24-pg`, for example) and a hint. Which runtime fits which placement is machine-readable in the catalog [GET /v1/infra/runtimes](./runtimes.md): every entry carries `supportedPlacements` — `["standalone"]` or `["standalone","galaxy"]`. The `name` and `packages` fields describe the dedicated-machine install and do not change. If a Galaxy app needs a database, take a language runtime and pass the connection string of an external (managed) DB through `env`, or deploy the app to a dedicated virtual machine with the original runtime.
- **The same runtime ID can mean different patch versions in Galaxy versus on a dedicated virtual machine.** In Galaxy the runtime is built from an official Docker image (`node:24-slim`, `node:20-slim`, `python:3.11-slim`, `python:3.12-slim`, `php:8.3-cli`, `nginx:alpine`) — the version follows the image tag, and the platform requests the latest version of that tag before every build. On a dedicated virtual machine the major version is pinned and matches what is advertised (Node.js 24, Node.js 20, Python 3.11, Python 3.12, PHP 8.3, PostgreSQL 16); the patch version follows the install source: every deploy updates Node.js 24 to the latest 24.x release from the official archive and verifies the Node.js release team's signature. If the exact version is critical, check it inside the app on the target placement rather than relying on the runtime ID alone.
- **`estimatedSetupTime` is an estimate, not a guarantee: budget twice the stated value when automating.**
- **If the stack you need is not in the list — use `preStart` on a dedicated virtual machine.** The server is a clean Ubuntu 24.04 with root access. In the deploy's `preStart` field you can run any `apt-get install`, download binaries, or set up the environment. The result is preserved between deploys (except for the `extractTo` directory, which `cleanDeploy: true` clears). For one-off operations — [`POST /exec`](./exec.md).

## See also

- [Create a server](/docs/infra/servers/create)
- [Full deploy](./deploy.md)
- [Get a server](/docs/infra/servers/get)
