Pour les agents IA : markdown de cette page — /docs-content-en/infra/galaxy-sleep.md index de la documentation — /llms.txt

Les articles de documentation sont actuellement disponibles en anglais.

Galaxy app sleep and wake

A Galaxy app goes to sleep when idle, together with the galaxy that carries it, and while it sleeps its container is stopped. This page describes what exactly stops, which fields report the real state, how to bring the app up and how long that takes.

What stops · State fields · How to bring it up · Logs · Recurring wake window

What stops during sleep

The app runs in a container on a shared host — the galaxy. Both parts can sleep, and these are different states.

What sleeps How it looks What it takes to bring up
The app container, the galaxy stays up The app does not respond, while neighbouring apps on the same galaxy keep working Starting the container — seconds
The galaxy together with every container on it No app of that galaxy answers Booting the galaxy machine, then starting the container — minutes

The persistent /data volume survives sleep. Waking starts the same container instead of creating a new one, so the lines the app wrote to its output stream before it slept are available after the wake too. A fully new container appears only on the next code upload, and that upload does not keep the previous container's log.

The status and reachability fields answer different questions

The status field in the GET /v1/infra/servers/:id response is the state of the app's record on the platform. A wake moves the record to running at the end, once the container is already started, so while the galaxy is coming up the record stays sleeping — on a cold machine that takes minutes. The opposite divergence is possible as well: the record can read running while the container is no longer working.

That is why the reachability block sits next to it — it answers the question "can the app respond right now". The block is present only for an app whose kind is GALAXY_APP; for every other server type it is null.

JSON
{
  "success": true,
  "data": {
    "id": "e22bb297-8a0a-4597-9b42-47d059cd1090",
    "kind": "GALAXY_APP",
    "status": "sleeping",
    "reachability": {
      "effectiveStatus": "running",
      "hostStatus": "running",
      "hostTunnel": "CONNECTED",
      "container": "running",
      "forwarder": "active",
      "publicEntry": "live",
      "probe": "ok",
      "probedAt": "2026-08-12T13:24:58.117Z"
    }
  }
}

Only the sleep-related fields are shown. For the full response, see GET /v1/infra/servers/:id.

Field Description
effectiveStatus The overall availability status — running, sleeping, waking, unreachable or unknown. How it is derived is shown in the table below
hostStatus State of the carrying galaxy, using the same values as the server status
hostTunnel The galaxy's connection to the platform — CONNECTED, DISCONNECTED or NONE
container The app container — running, stopped or unknown. The value unknown means the platform could not look, not that the container is stopped
forwarder Routing to the container on the host — active, inactive or unknown. It stops together with the container during sleep
publicEntry The app's public address — live (the gateway holds a live tunnel for the app subdomain), no-tunnel (there is no tunnel, so the address serves nothing from outside) or unknown (the gateway could not be asked). The value unknown never worsens the verdict
probe How the live host check ended — ok, host-down (the galaxy is asleep or unreachable and no check was sent), host-busy (the host is occupied by another operation), failed or not-attempted
probedAt Check time in ISO 8601. The value null means no check happened

How effectiveStatus is derived:

State effectiveStatus
The galaxy is booting waking
The galaxy is asleep sleeping
The galaxy is up, the container is stopped sleeping
The galaxy is up, the container is up, routing is active, the public address has a tunnel running
The galaxy is up, the container is up, routing is active, the public address has no tunnel unreachable
The galaxy is up, the container is up, routing is stopped unreachable
The galaxy is in error or lost its connection to the platform unreachable
The check could not be made unknown

The public entrance is checked separately. The container and the routing are measured on the galaxy itself, while the last leg of the path to https://app-XXXX.vibecode.bitrix24.com is the app's tunnel at the gateway, which is invisible from the galaxy: a started routing unit means it was started, not that it reached the gateway. So an app with a live container and active routing but no tunnel answers unreachable rather than running — that address serves nothing from outside. When the gateway's state could not be read, publicEntry is unknown and the verdict stays as it was: "could not look" is not "nothing works".

Important: the platform runs the live host check only while the galaxy is up and connected to the platform. Reading state never wakes a sleeping galaxy, so for a sleeping galaxy container and forwarder are always unknown and probe is host-down. The platform keeps the check result for a few seconds and serves it from memory: a check occupies the command channel shared by every app of the galaxy, so, thanks to this cache, frequent state polling does not tie it up.

How to bring a sleeping app up

Way What it does
POST /v1/infra/servers/:id/wake Brings the app up through its host. Boots the galaxy when needed, then starts the container
POST /v1/infra/servers/:id/start The same thing: for an app, the two calls are equivalent
Code upload Boots the galaxy itself and leaves the app running
A request to the app's address If waking is allowed, a request through the gateway brings the app up and answers with the BH_SERVER_WAKING code and a Retry-After header until it is ready — details in Authorization in a Black Hole app
Bitrix24 event delivery The platform brings the app up before delivering the event

The wake call returns immediately, not when the app is ready: an app has no cloud machine of its own, and the ?wait=true parameter does not make the call wait here. Check readiness by polling GET /v1/infra/servers/:id and reading reachability.effectiveStatus — the value waking means the galaxy is still booting.

How long to wait: the platform waits up to 15 minutes for a cold galaxy to come up, and expects the caller to wait as long. The exact budget is returned in the recovery.coldBootBudgetSeconds field when you read the logs of a sleeping app. An app on a galaxy that is already up starts in seconds.

A wake ban on the host blocks both calls, and /start does not lift it. The refusal codes are in the lifecycle table on the Galaxy app page.

When the app address has no tunnel, a confirmed wake ban is handled separately. Only in PUBLIC mode does the Gateway return 409 BH_APP_UNAVAILABLE without Retry-After: browsers show "App temporarily unavailable" and a "Refresh" button, while machine clients get JSON. The reason for the ban, balance information and platform brand are not disclosed, and neither waking nor automatic polling starts. An already open waiting page switches to this screen on its next poll. Once the ban is lifted, open the app again manually. In private mode, an identified user still receives 402 BH_WAKE_BLOCKED.

Logs of a sleeping app

Reading GET /v1/infra/servers/:id/logs wakes neither the app nor the galaxy. While the galaxy is asleep or unreachable, the response arrives with status 200, an empty data.logs array and two diagnostic fields.

JSON
{
  "success": true,
  "data": {
    "logs": [],
    "lines": [],
    "hint": "Galaxy host is asleep or unreachable, so the container log cannot be read right now. …",
    "recovery": {
      "reason": "The galaxy host carrying this container is not RUNNING + CONNECTED. …",
      "recoveryAction": "POST /v1/infra/servers/e22bb297-8a0a-4597-9b42-47d059cd1090/wake",
      "logsPreserved": true,
      "coldBootBudgetSeconds": 900,
      "poll": "GET /v1/infra/servers/e22bb297-8a0a-4597-9b42-47d059cd1090 (read `reachability`)",
      "wakeSchedule": { "available": true, "code": null }
    }
  }
}
Field Description
hint The same guidance as plain text, on one line. The wording depends on whether the caller is allowed to wake the app: when the caller can, the text names the wake call; when it cannot, the text names no wake address at all and instead names exactly the condition that applied to this caller. It names the second way to bring the app up only when that path is open to this caller — that is, together with the recovery.deliveryWakesHost field, not always
recovery.reason Why the log cannot be read right now
recovery.recoveryAction The WAKE call. The field is conditional — it may be absent. It is omitted whenever the caller is not allowed to wake the app; that set of states is open and grows, so branch on the PRESENCE of the field rather than on a list. Today it includes read-only mode, a Cowork/Code key, a disabled galaxy pilot, an agent maintenance key, an owner whose account deletion is pending, and reaching the app through its application link while another key owns the server. A wake ban on the galaxy HOST itself belongs to the same set: it refuses the wake for every caller, a fully privileged owner included, so the field is absent in that state too. Check that the field is present before reading it: in that state no field of the response carries a wake address — neither this one nor hint. Important: the converse is not a guarantee. The PRESENCE of the field means the wake is refused neither by the caller nor by a ban on the host — but not that the call will go through regardless: refusals by the STATE of the pair remain, and this log answer does not predict them (422 when the app is in the wrong status or the host did not boot, 404 when the galaxy is orphaned). Handle that refusal rather than treating the field's presence as a guarantee
recovery.logsPreserved The value true means lines written before the sleep are available after the wake
recovery.coldBootBudgetSeconds The budget for bringing a cold galaxy up, in seconds
recovery.poll What to check readiness with instead of reading the log again. The field is conditional — it may be absent. It is omitted when GET /v1/infra/servers/{id} refuses the caller itself: an agent maintenance key does not carry that route in its allowlist, and for an owner whose account deletion is pending it sits in the frozen surface, unlike this log read. If the field is absent, just read the log again later — the hint says the same
recovery.deliveryWakesHost The second way to bring the app up. The field is doubly conditional: it arrives only when waking is unavailable to the caller AND the deploy is available to them. action is the deploy call, cost states its price in words. A deploy to a sleeping galaxy app brings the host up by itself, but it is a CODE DEPLOYMENT that spends the balance, not a wake — do not call it just to read a log. Important: if the field is absent, that path is closed too: the read-only carve-out lifts the ACCESS-MODE gate on deploys and nothing else, and a Cowork/Code key, a disabled galaxy pilot and an agent maintenance key are refused the deploy by the same doors that refuse the wake. The field is also absent when waking is banned on the host — a deploy does NOT bring such a host up and answers 502 instead
recovery.wakeSchedule Whether a recurring wake window is available to this caller: the app's own eligibility and the caller's right to write, in one verdict. The available field is the answer, and on a refusal the code field carries the same code that creating the window would return. When recoveryAction is absent, the field comes back available: false with the code of the door that refused the wake — creating a window is the same write, refused by the same doors. The exception is a window door checked earlier than that one: then code names the window door, and hint names the same door rather than saying the wake's condition also refuses the window. Important: the window also has TWO doors of its own that the wake does not have, so code may name a refusal you will not find in the list of wake doors, and available: false may arrive while recoveryAction is present. The first is checked before every other door: the schedule route is outside the route allowlist of an external collaborator key, while the wake, deploy and log-read routes are all inside it — EXTERNAL_COLLABORATOR_KEY_OUT_OF_SCOPE. The second is checked after the mode, freeze, Cowork and pilot doors but BEFORE server ownership: the schedule route requires the vibe:infra scope, which reading logs and waking do not, so even an ordinary key without that scope reaches this refusal — INFRA_SCOPE_REQUIRED, and the cure is to grant the key that scope, not to change its mode. Because ownership is resolved after the scope, a caller admitted through the application link and lacking the scope gets INFRA_SCOPE_REQUIRED rather than NOT_FOUND

The sequence: bring the app up with the call from recovery.recoveryAction, wait until reachability.effectiveStatus is running, then read the logs again.

If the response carries no recoveryAction, the wake is refused. The cause is of one of two kinds, and hint names the one that applied: either a door of the caller itself (the list below), or a wake ban on the galaxy HOST — there the key is irrelevant, every caller is refused, and it is the account owner who lifts it. The wake call answers 403 SERVER_WAKE_BLOCKED in that state, and 402 with the subscription or plan wall code while the account's access is still lapsed. A recurring wake window can still be created in that state, but it will not bring the host up: the ban applies to a scheduled wake as well. There is no wake address in the prose either — in that state the answer deliberately names neither POST …/wake nor the creation of a scheduled window, which the same door refuses. Instead of an address, hint names exactly the condition that applied to this caller rather than a list joined by "or" — and it names the FIRST one in the order the doors actually refuse. That order is: an agent maintenance key does not carry the wake in its route allowlist; a pending account deletion closes the wake entirely, and changing the key does not help — the owner is frozen, not the key (delivery stays open there, see the second path below); the key mode is changed as described in Access mode; a Cowork/Code key has no access to the control plane at all; a disabled galaxy pilot is switched back on by the Bitrix24 account administrator; and last, reaching the app through its application link while another key owns the server: the wake checks ownership more strictly than the log read, so such a caller gets 404 and only a call by the server's owning key helps.

Some callers do have a way out, and it is not a wake. A key in read-only mode is allowed to deploy to a server it owns, and a deploy to a sleeping galaxy app brings the host up by itself. The same path is open to two more callers who are refused the wake: an owner whose account deletion is pending (the freeze sits on the /v1/infra plugin, while delivery lives in another one) and a caller admitted through the application link (delivery checks ownership more loosely than the wake). It is closed to exactly three: a Cowork/Code key, an agent maintenance key, and a caller on an account with the galaxy pilot switched off. When that path is open the platform exposes it in machine-readable form — the recovery.deliveryWakesHost field (action is the call, cost states the price in words) — and the price is not a formality: it is a code deployment and it spends the Vibecode balance, not a wake. Do not call it just to read a log.

It is not open to everyone, and the field is what tells you. The read-only carve-out lifts the ACCESS-MODE gate on deploys and nothing else. A Cowork/Code key has no access to the control plane at all, a disabled galaxy pilot refuses every non-GET in this family, and an agent maintenance key does not carry the deploy in its route allowlist — all three are refused POST …/deploy exactly as they are refused the wake. So check for deliveryWakesHost rather than assuming it: no field means no open path, and the condition named in hint is what has to change. Important: the converse is not guaranteed either, exactly as with recoveryAction: the field's presence means the deploy is refused neither by identity and key mode nor by a ban on the host. It does not answer for the state of the account AT THE MOMENT OF THE CALL: a balance freeze closes the whole /v1/infra family (402 ACCOUNT_FROZEN), and if it arrives after this read, the action it names gets exactly that — all the more so because a deploy spends balance by construction. Until the condition changes, repeating the log read in a loop is pointless: the answer stays the same.

Recurring wake window

A wake window brings the app up on a schedule, without a manual call. It is not available to every app, so check this against the platform's answer rather than a general rule: the recovery.wakeSchedule field in the response to a log read of a sleeping app gives a direct answer for that particular app and, on a refusal, the refusal code.

That answer is about the app and about the caller at once. Creating a window is still a write, so it is refused to a key in read-only mode, to a Cowork/Code key, and on a Bitrix24 account with the galaxy pilot switched off; in those states the field comes back available: false with the code of the door that refused. Wake availability is a good first signal — no recovery.recoveryAction means that caller cannot create a window either — but it is not the whole answer, because the window has two doors the wake does not: the route is outside the allowlist of an external collaborator key (EXTERNAL_COLLABORATOR_KEY_OUT_OF_SCOPE), and it requires the vibe:infra scope, which waking does not (INFRA_SCOPE_REQUIRED). Either one refuses the window even to a caller who can wake the app, so read recovery.wakeSchedule itself rather than deriving it from recoveryAction.

An app in a galaxy never gets the ALWAYS_ON_CONFLICT refusal: it does not choose its plan but inherits it from the galaxy, and the platform does not treat it as running in always-on mode. This also covers agents and bots: they have no idle timer of their own, but a wake window is available to them on the usual terms. The window's other refusals still apply — for example, WAKE_SCHEDULE_GALAXY_DISABLED when the capability for Galaxy apps is switched off on the platform.

Listing, creating, updating and deleting windows — Scheduled wake.

See also