For AI agents: markdown of this page — /docs-content-en/infra/database/snapshot.md documentation index — /llms.txt

Create a database backup

POST /v1/infra/servers/:id/db/backups

Queues a manual backup of the application's SQLite file. The backup is created in the background; the application keeps running during the backup.

Parameters

Parameter Type Required Description
Parameterid (path) Typestring (UUID) Requiredyes DescriptionID of an application with kind equal to GALAXY_APP. List: GET /v1/infra/servers

Request fields (body)

Field Type Required Description
Fieldfile Typestring Requiredno DescriptionDatabase file path relative to the /data volume, up to 1024 bytes in UTF-8. If the field is omitted, the file named in the application container's VIBE_DB_PATH variable is backed up, or app.db if the variable is not set. An absolute path, . and .. segments, empty segments and control characters are rejected. Database file list: GET /db

The body is optional: without a body or with an empty object {}, the default file is backed up. With the Content-Type: application/json header, the body cannot be empty — pass {}. The body accepts no other fields and is limited to 4 KiB.

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/APP_ID/db/backups" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/APP_ID/db/backups" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

JavaScript — personal key

javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db/backups`,
  {
    method: 'POST',
    headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({}),
  }
)
const { success, data, error } = await res.json()
if (!success) throw new Error(`${error.code}: ${error.message}`)
console.log('Backup queued:', data.backupId)

JavaScript — OAuth application

javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db/backups`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({}),
  }
)
const { success, data, error } = await res.json()
if (!success) throw new Error(`${error.code}: ${error.message}`)

Response fields

The HTTP status of a successful response is 202 Accepted: the backup has been queued but not created yet.

Field Type Description
Fieldsuccess Typeboolean Descriptiontrue when the backup has been queued
Fielddata.backupId Typestring DescriptionBackup ID. The backup appears under this id in GET /db/backups
Fielddata.status Typestring DescriptionAlways QUEUED

Response example

JSON
{
  "success": true,
  "data": {
    "backupId": "9e4d2c1b-6a3f-4b8e-a7d5-0c1f2e3d4b5a",
    "status": "QUEUED"
  }
}

Error response example

409 — a repeated request right after creating a backup; the previous backup of this application has not completed yet:

JSON
{
  "success": false,
  "error": {
    "code": "APP_DB_BUSY",
    "message": "The database is busy with a live write, retry shortly",
    "details": {
      "source": "sqlite",
      "retryable": true,
      "retryAfterSeconds": 1
    }
  }
}

Errors

HTTP Code Description
HTTP400 CodeVALIDATION_ERROR DescriptionThe body contains an unknown field or file violates the path rules
HTTP400 CodeFST_ERR_CTP_EMPTY_JSON_BODY DescriptionThe Content-Type: application/json header was passed without a body. Pass {} or remove the header
HTTP400 CodeAPP_DB_INVALID_FILE DescriptionThe file field was not passed, and the container's VIBE_DB_PATH value does not point to a valid path inside /data
HTTP400 CodeAPP_DB_UNSUPPORTED_PLACEMENT DescriptionThe application is not hosted in Galaxy
HTTP401 CodeMISSING_API_KEY DescriptionThe X-Api-Key header is missing
HTTP401 CodeINVALID_API_KEY DescriptionThe key is not recognized
HTTP402 CodeBILLING_FROZEN DescriptionThe portal balance is frozen; the backup was not queued
HTTP402 CodeBILLING_INSUFFICIENT DescriptionThe portal balance is exhausted and storage is suspended. The backup was not queued
HTTP403 CodeINFRA_SCOPE_REQUIRED DescriptionThe key lacks the vibe:infra scope
HTTP403 CodeAPP_DB_READONLY_KEY DescriptionThe key was issued as read-only
HTTP403 CodeAPP_DB_DISABLED DescriptionApplication database access is not enabled for the portal
HTTP403 CodeSERVER_WAKE_BLOCKED DescriptionThe host is asleep and waking it is blocked
HTTP404 CodeNOT_FOUND DescriptionThere is no application with this id on the portal, it has been deleted, or the key has no access to it
HTTP404 CodeAPP_DB_NOT_FOUND DescriptionThe application has no data volume
HTTP409 CodeAPP_DB_BUSY DescriptionThe application is busy: the previous backup is still QUEUED or RUNNING, or a database restore, deploy or migration of the application is in progress. With details.source equal to host — another application's database is being restored on the host, the host is busy with another operation, or the host has not responded. Retry after details.retryAfterSeconds seconds
HTTP413 CodePAYLOAD_TOO_LARGE DescriptionThe body exceeds 4 KiB
HTTP429 CodeRATE_LIMITED DescriptionThe write request limit for the portal was exceeded — Limits. Retry after the delay in the Retry-After header
HTTP503 CodeAPP_DB_TOOL_UNAVAILABLE DescriptionThe host is not prepared for database operations, or the platform temporarily cannot reach it. Host readiness — GET /app-db/prepare
HTTP503 Codeuser_self_deletion_pending DescriptionThe key owner requested deletion of their account on the portal. Access returns after the deletion is cancelled

Full list of common API errors — Errors.

Known specifics

Backup readiness. A 202 response does not mean the backup has been created. Poll GET /db/backups and look for the item with id equal to backupId: the backup is ready when status is COMPLETED, and if it is FAILED, errorCode gives the cause. On a test application with a 937-byte backup, the backup went from QUEUED to COMPLETED in 1 min 40 s.

One backup at a time. Until the application's previous backup completes, retries after details.retryAfterSeconds get the same 409 APP_DB_BUSY. The message text does not name the cause: with details.source equal to sqlite, it refers to a database write even when the database is occupied by an unfinished backup. Instead of retrying frequently, poll the backup list until the backup completes.

Where backups are stored, how long they live and how they are billed — Backups and retention.

See also