For AI agents: markdown of this page — /docs-content-en/infra/database/restore.md documentation index — /llms.txt
Restore the database from a backup
POST /v1/infra/servers/:id/db/restore
Replaces the application's SQLite file with the contents of a completed database backup. The restore runs in the background, and before the replacement the platform saves a protective backup of the current file.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typestring (UUID) | Requiredyes | DescriptionID of an application with kind equal to GALAXY_APP whose database is to be replaced. List: GET /v1/infra/servers |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldbackupId |
Typestring | Requiredyes | DescriptionID of a backup with status COMPLETED and an unexpired expiresAt. List: GET /db/backups, the data.items[].id field. The backup may belong to another application in the same Bitrix24 account, including a deleted one, if the key has access to that application's data. Backups of another application: GET /db/backups?sourceAppId=... |
Fieldfile |
Typestring | Requiredno | DescriptionPath of the file to replace relative to the /data volume, up to 1024 bytes in UTF-8. Without the field, the file set in the application container's VIBE_DB_PATH variable is replaced, or app.db if the variable is not set. An absolute path, . and .. segments, empty segments and control characters are rejected |
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/restore" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"backupId":"BACKUP_ID"}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/APP_ID/db/restore" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"backupId":"BACKUP_ID"}'
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db/restore`,
{
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ backupId }),
}
)
const { success, data, error } = await res.json()
if (!success) throw new Error(`${error.code}: ${error.message}`)
// Restore progress is in data.restore of the GET /db/backups response with the same restoreId
console.log('Restore accepted:', data.restoreId)
JavaScript — OAuth application
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db/restore`,
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ backupId }),
}
)
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 restore has been queued, and the database has not been replaced yet.
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue when the restore has been queued |
Fielddata.restoreId |
Typestring | DescriptionRestore ID. Use it to find the restore in the data.restore field of the GET /db/backups response |
Fielddata.backupId |
Typestring | DescriptionBackup ID from the request |
Fielddata.targetAppId |
Typestring (UUID) | DescriptionID of the application whose database is being replaced — the id value from the path |
Fielddata.status |
Typestring | DescriptionAlways QUEUED |
Response example
{
"success": true,
"data": {
"restoreId": "cm2r7x4k10003qv8n5d2b6w1z",
"backupId": "9e4d2c1b-6a3f-4b8e-a7d5-0c1f2e3d4b5a",
"targetAppId": "5c0e8f2a-3d1b-4a7e-9f60-2b8c4d1e7a93",
"status": "QUEUED"
}
}
Error response example
404 — there is no backup with this backupId:
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Server not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeVALIDATION_ERROR |
DescriptionbackupId is missing, the body contains an unknown field, backupId has invalid characters or file violates the path rules |
| 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 |
| 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 |
| HTTP404 | CodeNOT_FOUND |
DescriptionThere is no application with this id on the portal, it was deleted or the key has no access to it |
| HTTP404 | CodeNOT_FOUND |
DescriptionThere is no backup with this backupId on the portal, it is not yet in status COMPLETED, its retention period has expired or the key has no access to the data of the application it was taken from. The message text is the same for both NOT_FOUND cases |
| HTTP404 | CodeAPP_DB_NOT_FOUND |
DescriptionThe application has no data volume |
| HTTP409 | CodeAPP_DB_BUSY |
DescriptionThe restore was not accepted: the application has a backup, another restore, a database write, a deploy or migration in progress, waking the application or host is blocked, or the portal balance is frozen. Retry after details.retryAfterSeconds seconds |
| HTTP413 | CodePAYLOAD_TOO_LARGE |
DescriptionThe body exceeds 4 KiB |
| HTTP422 | CodeAPP_DB_BACKUP_INVALID |
DescriptionThe backup is completed, but it lacks the data required for a restore |
| HTTP429 | CodeRATE_LIMITED |
DescriptionThe write request limit for the portal was exceeded — Limits. The pause is 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 is restored once the deletion is cancelled |
Full list of common API errors — Errors.
Known specifics
Restore progress. A 202 response means only that the request was accepted. Read the state in data.restore of the GET /db/backups response, matching restoreId. On a test application, the restore took 12 minutes and went through the phases in order: VALIDATE, PREPARE, PRE_CHANGE, STAGE, STOPPING, SWAPPING, VERIFY, STARTING, CLEANUP. After completion, the database data matched the backup. The restore stays in status QUEUED while another restore is running on the platform or a backup or database write is in progress on the same host.
The database is busy until the restore ends. Until the restore completes, writes to this application's database and new backups return 409 APP_DB_BUSY. Reads also get 409 APP_DB_BUSY: on a live call, a read right after the restore started returned this response, and from the STOPPING phase reads are blocked until the restore ends.
Application restart. A running application is stopped in the STOPPING phase and started again in the STARTING phase. An application that was stopped before the restore stays stopped.
Protective backup before the replacement. In the PRE_CHANGE phase, the platform saves the current file as a backup with triggerType equal to PRE_CHANGE — it is visible in the backup list. To undo the restore, restore the database from this backup. If the protective backup could not be created, the restore ends with status FAILED and the file is not replaced. If the file specified by file does not exist yet, no protective backup is created.
Failure during the replacement. A failure in the VALIDATE, PREPARE or PRE_CHANGE phase does not touch the file. A failure in the phases from STAGE to VERIFY returns the original file through the ROLLBACK phase. In both cases, the restore ends with status FAILED and errorCode equal to APP_DB_RESTORE_FAILED. A failure in the STARTING phase or three failed ROLLBACK attempts move the restore to the RECOVERY_REQUIRED phase with status RUNNING without an automatic rollback: from the STARTING phase the application is already running on the restored database. Such a restore waits for support to intervene, and the application's database stays busy until then.
Database access conditions and backup retention rules — When the database is available and Backups and retention.