For AI agents: markdown of this page — /docs-content-en/infra/lifecycle/wake.md documentation index — /llms.txt
Wake server
POST /v1/infra/servers/:id/wake
Wakes a server from sleeping or provisioning. Unlike /start, /wake supports a blocking mode via ?wait=true — the response is returned only when the server is fully ready (the virtual machine has started and the tunnel has connected) or the timeout fires. While waiting, the platform re-checks the machine state with the cloud and re-issues the start command if it never landed; a connected tunnel counts as proof of readiness even when the server status has not refreshed yet. Use the blocking mode when the client needs readiness before the next step (a cron job, a triggered call), and the asynchronous one when you can afford to poll.
Parameters
| Parameter | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
id |
path | string (UUID) | yes | — | ID of a server in sleeping or provisioning status |
wait |
query | string | no | — | true — blocking mode: the response returns only when the server is ready (up to 6.5 minutes) or the timeout fires. Any other value — asynchronous mode, the response returns immediately |
The request body is empty.
Examples
curl — personal key
# Asynchronous call — responds immediately, check readiness by polling
curl -X POST -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/wake
# Blocking — waits for readiness up to ~6.5 minutes
curl -X POST -H "X-Api-Key: YOUR_API_KEY" \
"https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/wake?wait=true"
curl — OAuth application
curl -X POST -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
"https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/wake?wait=true"
JavaScript — personal key
// Blocking variant — simplest for subsequent steps
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/wake?wait=true`,
{ method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const body = await res.json()
if (!body.success) {
// Rich error: show userMessage to the user, offer alternatives
console.error(body.error.userMessage ?? body.error.message)
if (body.error.alternatives) console.log('Options:', body.error.alternatives)
throw new Error(body.error.code)
}
console.log(`Server ready: ${body.data.appUrl}`)
JavaScript — OAuth application
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/wake?wait=true`,
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
}
)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | true on a successful wake |
data.id |
string (UUID) | Server ID |
data.status |
string | Current status in lowercase (running on success with wait=true; provisioning in asynchronous mode) |
data.blackholeStatus |
string | Tunnel state (CONNECTED in blocking mode on success) |
data.appUrl |
string | null | HTTPS address of the application |
Response example
Successful wake (?wait=true):
{
"success": true,
"data": {
"id": "e765edfc-ba0a-43de-b8ea-838dd872c522",
"status": "running",
"blackholeStatus": "CONNECTED",
"appUrl": "https://app-05b67cf7.vibecode.bitrix24.com"
}
}
Error response example
402 — a commercial plan is required (rich error for AI agents):
{
"success": false,
"error": {
"code": "COMMERCIAL_PLAN_REQUIRED",
"message": "Waking this server requires a commercial Bitrix24 plan or an active trial",
"userMessage": "Waking the server requires a commercial Bitrix24 plan or an active trial. Get a plan at https://www.bitrix24.com/prices/",
"alternatives": [
"Upgrade the Bitrix24 plan and retry",
"Switch to AI Router with BYOK keys — it works on any plan"
],
"hint": "Do not retry automatically — a user action is required"
}
}
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 |
| 402 | COMMERCIAL_PLAN_REQUIRED |
The plan is free and the trial is unavailable — upgrade your Bitrix24 plan |
| 402 | INT_TARIFF_REQUIRED |
The Bitrix24 plan is free — waking requires a commercial plan (a trial plan grants limited access). For a Galaxy app the same code answers a wake stopped by the account access check on the galaxy host |
| 402 | TRIAL_EXPIRED |
The trial was used and has ended |
| 402 | BILLING_EXHAUSTED |
The Vibecode balance is exhausted — top it up |
| 402 | ACCOUNT_FROZEN |
The balance is frozen |
| 402 | INT_VIBE_PLUS_REQUIRED |
A Galaxy app: access is narrowed to the Vibe+ plan line and the account is on an ordinary commercial plan, so the access check stops the wake of the galaxy host. Code breakdown — Errors |
| 403 | SERVER_WAKE_BLOCKED |
Wake blocked for a non-billing reason (an ended trial, an administrative block, security violations). For a Galaxy app the same code is returned when waking is blocked on the galaxy host |
| 403 | INFRA_FORBIDDEN_FOR_COWORK_KEY |
The call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy |
| 404 | NOT_FOUND |
The server is not in sleeping/provisioning status, was deleted, or belongs to another API key while you are not on its development team |
| 404 | GALAXY_HOST_NOT_FOUND |
A Galaxy app: the galaxy host it runs on was not found |
| 422 | VM_MISSING |
The record has no externalId — the virtual machine was not created on the provider side. Delete the server and create a new one |
| 422 | SERVER_WRONG_STATE |
A Galaxy app whose code has never been uploaded, or an app in error status: /wake does not recover a failed build. error.message names the code-upload call that fixes this |
| 422 | CREDENTIAL_MISSING |
A Galaxy app: the galaxy host has no cloud-provider access attached — contact support |
| 429 | RATE_LIMITED |
The request rate limit was exceeded. The response carries a Retry-After header with the recommended pause |
| 502 | PROVIDER_ERROR |
The cloud provider returned an error while starting the virtual machine |
| 503 | WAKE_TIMEOUT |
The blocking ?wait=true call timed out (~6.5 minutes) before the server became ready: either the machine never came up or the tunnel never connected. The server returns to sleeping — a repeat call is safe |
The full list of common API errors — Errors.
Known specifics
- Behavior on a
?wait=truetimeout. If the virtual machine has not come up within ~6.5 minutes, the endpoint returns503 WAKE_TIMEOUTand tries to roll the server back tosleeping— so the quota is not left hanging on a "forever stuck" server. Inside that window the platform re-issues the start command whenever the cloud loses it, so a timeout means the machine genuinely did not come up, not that the command went missing. Retry/wakeor call/repair. - Rich-error fields for AI agents. On 402/403 the error body additionally contains
userMessage(a localized message for the user),alternatives(a list of resolution paths), andhint(advice to the AI agent on whether to retry automatically or not). Use these fields in the UI instead of the barecode/message. - A request to the subdomain does not always wake the server. A wake is triggered in four cases: the server has access policy
PUBLIC, the visitor is authenticated, the request carries an access token inapi-bearermode, or the recipient opens ashare-urllink. A server with a wake block does not come up in these cases either — see the item below. An unauthenticated request to a server with any other policy, including the defaultOWNER_ONLY, leaves the server insleepingstatus: a regular request gets the sign-in page with status200, and an API client — that is, a request carryingAccept: application/json,Authorization: Bearer, orX-Requested-With: XMLHttpRequest, as well as any request under the/api/path — gets401 BH_LOGIN_REQUIRED. On a server with policyPUBLIC,GETandHEADrequests from search crawlers and automated clients — for examplecurl,wget,python-requests,go-http-client,java/, headless browsers, and a request with noUser-Agentheader — do not bring the machine up, so that crawling does not keep it running. On such a serverPOST,PUT,PATCH, andDELETErequests wake it from any client: those are webhook and API calls, not crawling. From a script or a console, bring the server up with an explicit/wakeandwait=true— then the response arrives once the server is already accepting requests. - A server with the
preventWakeflag is not brought up by/wake— the refusal codes are in the table above. The platform sets this flag when the balance is frozen, the trial period ends, or an administrative block is applied, and a server that belongs to an agent or a bot gets it on any stop — from its card or through/sleep-now. A standalone server is brought up by/start: it clears the block, but does not bypass a frozen balance. For a Galaxy app, a block on the host blocks/startas well — see Galaxy app. - Check availability BEFORE the call. Before calling
/wake, callGET /v1/meand look atcapabilities.servers.wake.available. If it isfalse, the user must take action (top up the balance, upgrade the plan) before waking becomes possible. - The machine's public address is different after a wake. A woken machine receives a new address, so the
ipfield inGET /v1/infra/servers/:idreturns a different value after every sleep cycle. This applies to all plans. Whatever reaches the server by its address — a DNS record, external monitoring — should point at the HTTPS subdomain in theappUrlfield instead: a wake does not change it. The opposite direction has no such fix: when an external service admits only an allowlist of IPs, there is nothing to put on that list — the platform provides no permanent outbound address in any placement model, see Outbound IP. /wakeis not suitable for anerrorserver — use/startor/repair.
Galaxy apps (`kind=GALAXY_APP`)
On a Galaxy app, ?wait=true does not wait for readiness: the response arrives immediately, and the WAKE_TIMEOUT code never occurs here. After a cold host boot the app stays in sleeping status for a while — track readiness by polling GET /v1/infra/servers/:id.
The full map of an app's lifecycle operations is on the Galaxy app page.