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 — the balance is frozen, and the server will not come up until the balance is topped up (rich error for AI agents):
{
"success": false,
"error": {
"code": "BILLING_EXHAUSTED",
"message": "Balance depleted — top up to resume",
"userMessage": "Your Vibecode balance is empty. Top up to resume your servers.",
"alternatives": [
{ "type": "topup", "description": "Top up your balance in the billing section" }
],
"hint": "Ask the user to top up their VibeCode balance. After top-up the server can be woken normally."
}
}
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 |
| 402 | INT_TARIFF_REQUIRED |
A Galaxy app: the account access check stops the wake of the galaxy host because the Bitrix24 account is on a free plan. A dedicated virtual machine does not get this code — its wake does not check the plan |
| 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 | VIBE_DEMO_EXPIRED |
The server is a Vibe+ trial machine and the trial has ended: the platform froze it at the scheduled access check and refuses to wake it. This check runs before the wake-block and billing checks. The server and its data are kept; a paid Vibe+ plan on the Bitrix24 account restores access; the server is not started automatically — start it with a new call |
| 403 | SERVER_WAKE_BLOCKED |
Wake blocked for a non-billing reason (expired platform access, 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 |
| 403 | EXTERNAL_COLLABORATOR_KEY_SERVER_MISMATCH |
The call was made with an external-collaborator key, and the address names a server other than the one the key was issued for. Such a key is valid for exactly one server, and the response does not reveal whether the requested server exists. Working with another server requires the key issued for that external membership |
| 403 | EXTERNAL_COLLABORATOR_NOT_A_MEMBER |
An external-collaborator key addresses its own server, but access is not granted right now: the membership was removed, it expired, or external development collaborators are switched off for the Bitrix24 account that owns the server. The code does not tell these reasons apart and reveals nothing about the server. Membership is re-read on every request, so revoked access stops working immediately |
| 404 | SERVER_NOT_FOUND |
The server does not exist, was deleted, or belongs to another API key while you are not on its development team |
| 404 | NOT_FOUND |
The server was deleted while the call was in progress |
| 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 and the cloud review sees no machine under this server's cloud name — the virtual machine was not created on the provider side. Replace the server: delete it and create a new one. error.hint names the endpoint of each step only if that step is available to this request, and for an unavailable step it gives the reason for the refusal and what to change. The error.userMessage field arrives only when both steps are available |
| 422 | VM_POINTER_LOST |
The record has no externalId, but the cloud review does see a machine under this server's cloud name: the link is lost while the machine itself is most likely running and billed. Do NOT delete the server and create a new one — that would leave the machine running with no record at all. The server is not moved to error; contact support to have the link restored |
| 422 | SERVER_WRONG_STATE |
The server is not in sleeping or provisioning status, so /wake does not apply to it. The response carries currentState and availableActions — the server's current state and the actions available for it. A Galaxy app that has never had code uploaded and an app in error status get the same refusal: /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 and gets an authentication refusal. Both representations use HTTP401: browser navigation gets the HTML sign-in page, while a machine-shaped request gets JSONBH_LOGIN_REQUIRED. JSON is selected byAccept: application/json,Content-Type: application/json,Authorization: Bearer,X-Api-Key,X-Requested-With: XMLHttpRequest, a/v1/…or/api/…path, or any non-navigationSec-Fetch-Destvalue (includingempty); a request with neither explicit HTML nor a destination also defaults to JSON. These signals take precedence over explicit HTML andSec-Fetch-Dest: document|iframe|frame. A barePOSTwithAccept: */*therefore gets JSON401. 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 flag is set when the balance is frozen, platform access 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, waking is unavailable right now: the balance is frozen or the key is restricted, and thereasonfield names the cause. The flag accounts for neither the plan nor the server's own wake block, so403 SERVER_WAKE_BLOCKEDis possible even when it istrue. - 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.