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
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
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
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
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
{
"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:
{
"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.