For AI agents: markdown of this page — /docs-content-en/source-storage/auto-save.md documentation index — /llms.txt

Automatic save on deploy

The platform saves a source snapshot by itself, on every successful deployment. This page covers what goes into a snapshot automatically, how to read the outcome in the deploy response, when saving is skipped, and the three cases where a snapshot is still saved by hand.

Storage overview and the endpoint reference — Source code storage.

Saving sources

Since the 2026-05-23 release the platform automatically saves the source bytes to storage on every successful deployment. This applies to:

  • POST /v1/infra/servers/:id/deploy { source: { content: <base64> } } — the inline bytes are saved as a new version
  • POST /v1/infra/servers/:id/deploy { source: { url: <signed URL from storage> } } — the existing version is linked to the deployment identifier
  • POST /v1/infra/servers/:id/deploy { source: { versionId: 'vN' } } — the same

For a Galaxy app, deploying from a link or a saved version must be enabled for you separately. On standalone virtual machines (kind is STANDALONE) every variant from the list above works. For a Galaxy app (kind is GALAXY_APP) the inline source.content always works, while source.url and source.versionId work where the platform has enabled link deploys for you; otherwise the request is rejected with 400 GALAXY_DEPLOY_CONTENT_ONLY. On a Galaxy app the link itself must point at this storage — an outside address is rejected with 400 GALAXY_SOURCE_URL_NOT_ALLOWED. See Galaxy app for details.

Exception: deployment with an external URL (not from Vibecode storage) returns 409 SNAPSHOT_REQUIRED. To work around it — either first upload an archive via POST /v1/apps/:id/sources and deploy via {source: {versionId: 'vN'}}, or pass the X-Skip-Source-Snapshot: <reason> header to explicitly opt out.

Deploy response: the `source` block

The POST /v1/infra/servers/:id/deploy response includes a data.source block — the auto-save outcome. An AI agent or client reads it to tell whether the code reached storage:

JSON
{
  "success": true,
  "data": {
    "status": "running",
    "appUrl": "https://app-b7c1e2a4.vibecode.bitrix24.com",
    "source": {
      "autoSaved": true,
      "savedVersionId": "v4",
      "sha256": "a3f5d8b2c1e9f4...",
      "linkedDeployId": "deploy:2026-05-21T10:15:30.000Z",
      "skippedReason": null
    }
  }
}
Field Type Description
source.autoSaved boolean true — snapshot saved; false — skipped (reason in skippedReason)
source.savedVersionId string | absent Identifier of the created version (vN) when autoSaved: true
source.sha256 string | absent SHA-256 of the saved archive
source.linkedDeployId string | absent Identifier of the deployment the snapshot is linked to
source.skippedReason string | null null on success; otherwise the skip reason (see below)

The deployment completes successfully (200) regardless of the source block — auto-save is best-effort and never fails the deployment. Values of skippedReason:

skippedReason When
feature-disabled-platform Source deposit is disabled at the platform level
feature-disabled-portal The Bitrix24 account owner disabled source deposit for their account
external-url-or-toggles-off The source is an external URL (not from Vibecode storage)
save-failed Transient storage error — retry the deploy or save manually via POST /v1/apps/:id/sources
<header value> X-Skip-Source-Snapshot: <reason> was passed — the snapshot was skipped intentionally

To confirm the code was deposited, check data.source.autoSaved === true and store savedVersionId for later rollback or handoff.

When a snapshot is not created

If source saving is disabled for the Bitrix24 account or the source is an external URL (not Vibecode storage), no snapshot is created and the deployment completes normally. To save a version explicitly, upload an archive via POST /v1/apps/:id/sources.

When `POST /sources` is still needed explicitly

Only three scenarios:

  1. Mark a version — set a manual or published tag so the version is stored indefinitely.
  2. Save without deploying — record an intermediate result for handoff to another developer.
  3. Prepare for a rollback — a snapshot of the initial state before a risky change.

When to call

Typical scenario for an AI agent (since 2026-05-23 an explicit POST /sources call before deploy is not required — the platform saves automatically):

  1. Change the code → POST /v1/infra/servers/:id/deploy — sources are saved automatically.
  2. POST /v1/apps/:id/publish — publishes the application to the Bitrix24 catalog. The published tag is added to the snapshot automatically.
  3. Repeat the cycle on the next change.

Scenario for handing the project to a new developer or a new AI session:

  1. GET /v1/apps/:id/sources — list of available versions.
  2. GET /v1/apps/:id/sources/:versionId/download — signed link to the archive.
  3. Download the archive, unpack it, and continue work.

For MCP clients: the save_sources tool packs the file tree into tar.gz on the client side and sends it in a single request. The load_sources tool downloads the latest version and unpacks it back into a file tree. A direct HTTP endpoint call is available for clients that pack the archive themselves.

Deploy from a snapshot

POST /v1/infra/servers/:id/deploy accepts the source.versionId field — an alternative to source.url and source.content. It lets you deploy the exact version saved via save_sources to the server, without a separate file upload.

JSON
{
  "source": {
    "versionId": "v3"
  },
  "start": "node server.js"
}

The server resolves versionId into a signed link to the archive and performs the deploy. After a successful or failed deploy, the snapshot's linkedDeployId field is updated automatically.

On a Galaxy app, this must be enabled for you separately. Deploy by source.versionId works on servers whose kind is STANDALONE. A Galaxy app (kind is GALAXY_APP) accepts source.versionId and source.url where the platform has enabled link deploys for you; otherwise the request is rejected with 400 GALAXY_DEPLOY_CONTENT_ONLY and only the inline source.content remains. On a Galaxy app the link must point at this storage — an outside address is rejected with 400 GALAXY_SOURCE_URL_NOT_ALLOWED. See Galaxy app for details.

How the version is resolved. When the server belongs to the same key that makes the call, the version is looked up in that server's context — this is what makes the "save through POST /v1/infra/servers/:id/sources, then deploy by versionId" pair work, including on a personal key (vibe_api_*). If the server holds no such version and the owning key is bound to an application, the lookup is repeated in the application's context — that is what deploys a version saved before the server was replaced. Not found in either context — 404 SOURCE_VERSION_NOT_FOUND.

Restriction: it has narrowed and now applies only when the server belongs to a key other than the calling one — a management key, or access through an application card. There the version is still looked up in the application's context only, and when the server's owning key is not bound to an application, 400 SOURCE_VERSION_REQUIRES_APP is returned.

Behavior for AI models

The save_sources MCP tool wraps POST /v1/apps/:id/sources. The load_sources tool downloads and unpacks the latest snapshot into a file tree.

Since 2026-05-23 an explicit save_sources call before deployment is not required — the platform saves the bytes automatically. save_sources is still needed only for the three explicit scenarios (the "Saving sources" section above).

Channels through which the model learns about source saving:

  • The descriptions of the save_sources and load_sources MCP tools — visible on first use.
  • The hint in the 409 SNAPSHOT_REQUIRED response (deployment with an external URL) — suggests uploading via POST /sources or passing X-Skip-Source-Snapshot.
  • The hint in the 409 SNAPSHOT_REQUIRED response (publishing without a saved snapshot) — guides the model into the publish → save_sources → publish cycle (relevant if the source is an external URL and auto-saving was skipped).
  • The capabilities.apps.sourceStorage block in the GET /v1/me response — a programmatic state check.

See also