## Get database information

`GET /v1/infra/servers/:id/db`

Returns the SQLite files in the application's data volume, the default file, the capabilities available to the key and the latest completed backup of the default file. Call it before reading the schema and rows to find out which file to open.

Database access conditions and request limits — [When the database is available](/docs/infra/database#when-the-database-is-available) and [Limits](/docs/infra/database#limits).

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|----------|
| `id` (path) | string (UUID) | yes | ID of an application with `kind` equal to `GALAXY_APP`. List: [`GET /v1/infra/servers`](/docs/infra/servers/list) |
| `file` (query) | string | no | Non-empty string of at most 1024 UTF-8 bytes. This request ignores it: the file list, `defaultFile`, `defaultFileExists` and `lastBackup` do not depend on it. The default file comes from the container's `VIBE_DB_PATH`, or `app.db` when unset |

The endpoint accepts no other query string parameters: an unknown parameter returns `400 VALIDATION_ERROR`.

## Examples

### curl — personal key

```bash
curl "https://vibecode.bitrix24.com/v1/infra/servers/APP_ID/db" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl "https://vibecode.bitrix24.com/v1/infra/servers/APP_ID/db" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db`,
  { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const { success, data, error } = await res.json()
if (!success) throw new Error(error.code)
if (!data.defaultFileExists) console.log('The application has not created a database yet')
console.log(data.defaultFile, data.files)
```

### JavaScript — OAuth application

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${appId}/db`,
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
const { success, data, error } = await res.json()
if (!success) throw new Error(error.code)
console.log(data.defaultFile, data.files)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on success |
| `data.files` | array | Discovered SQLite files, in alphabetical order. An empty array if there is no volume or it contains no databases |
| `data.files[].file` | string | File path relative to `/data`. Pass this value in the `file` parameter of the other endpoints in this section |
| `data.files[].sizeBytes` | number | Size of the main database file in bytes, excluding the `-wal` and `-shm` journal files |
| `data.defaultFile` | string | Default file: the `VIBE_DB_PATH` value from the application container without the `/data/` prefix, otherwise `app.db` |
| `data.defaultFileExists` | boolean | Whether the default file exists |
| `data.truncated` | boolean | `true` if the volume scan stopped early: the volume has more than 1000 entries, 500 files were found, directory nesting exceeds 8 levels or the list approached 1 MiB |
| `data.capabilities.read` | boolean | Database reads. Always `true` |
| `data.capabilities.write` | boolean | Database writes. `false` for a read-only key |
| `data.capabilities.backups` | boolean | Working with backups. Always `true` |
| `data.lastBackup` | object \| null | Latest backup of the default file with status `COMPLETED`. `null` if there are no such backups |
| `data.lastBackup.id` | string | Backup ID. Pass it to [`POST /db/restore`](/docs/infra/database/restore) |
| `data.lastBackup.sourceAppId` | string | ID of the application the backup was taken from |
| `data.lastBackup.platformPaid` | boolean | `true` if the platform pays for storing the backup |
| `data.lastBackup.captureScope` | string | What was backed up. Always `SQLITE` — a single database file |
| `data.lastBackup.status` | string | Backup status. Always `COMPLETED` here |
| `data.lastBackup.triggerType` | string | Backup reason: `MANUAL`, `SCHEDULED`, `PRE_CHANGE`, `PRE_DELETE` |
| `data.lastBackup.file` | string \| null | Path of the backed-up file relative to `/data` |
| `data.lastBackup.sizeBytes` | string \| null | Backup size in bytes, a decimal number as a string |
| `data.lastBackup.createdAt` | string (ISO 8601) | When the backup was queued |
| `data.lastBackup.completedAt` | string (ISO 8601) \| null | When the backup became ready |
| `data.lastBackup.expiresAt` | string (ISO 8601) \| null | When the backup will be deleted |
| `data.lastBackup.errorCode` | string \| null | Backup error code. `null` for a completed backup |

Each backup in the [backup list](/docs/infra/database/backups) has the same fields.

## Response example

```json
{
  "success": true,
  "data": {
    "files": [
      {
        "file": "app.db",
        "sizeBytes": 20480
      }
    ],
    "defaultFile": "app.db",
    "defaultFileExists": true,
    "truncated": false,
    "capabilities": {
      "read": true,
      "write": true,
      "backups": true
    },
    "lastBackup": {
      "id": "3f6d2a91-8b4e-4c17-a5d0-9e1b7c4f2a68",
      "sourceAppId": "7c2b1f08-3a4d-4e91-9b6c-2f5e8a1d0c33",
      "platformPaid": false,
      "captureScope": "SQLITE",
      "status": "COMPLETED",
      "triggerType": "MANUAL",
      "file": "app.db",
      "sizeBytes": "937",
      "createdAt": "2026-10-20T08:26:17.942Z",
      "completedAt": "2026-10-20T08:28:00.046Z",
      "expiresAt": "2026-10-27T08:28:00.046Z",
      "errorCode": null
    }
  }
}
```

## Error response example

503 — the galaxy host has no service image for reading the database:

```json
{
  "success": false,
  "error": {
    "code": "APP_DB_TOOL_UNAVAILABLE",
    "message": "Database reading infrastructure is unavailable, retry shortly",
    "details": {
      "retryable": true,
      "retryAfterSeconds": 1
    }
  }
}
```

If the error persists, check the [host preparation status](/docs/infra/database/prepare-status) and, if needed, [prepare the host](/docs/infra/database/prepare).

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | A query string parameter other than `file` was passed, or `file` is empty or longer than 1024 bytes |
| 400 | `APP_DB_INVALID_FILE` | The `VIBE_DB_PATH` variable in the application container points outside `/data` or contains an invalid path |
| 400 | `APP_DB_UNSUPPORTED_PLACEMENT` | The application is not hosted in Galaxy |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 401 | `INVALID_API_KEY` | The key is not recognized |
| 402 | `BILLING_FROZEN` | The galaxy host is asleep and the balance is frozen — the host cannot be woken |
| 403 | `INFRA_SCOPE_REQUIRED` | The key lacks the `vibe:infra` scope |
| 403 | `APP_DB_DISABLED` | Database access is not enabled for the portal |
| 403 | `SERVER_WAKE_BLOCKED` | The galaxy host is asleep and waking it is blocked |
| 404 | `NOT_FOUND` | The application does not exist, was deleted or is not accessible to this key |
| 409 | `APP_DB_BUSY` | The host is busy with another operation or did not connect within 10 seconds. The response carries a `Retry-After` header. If the host is busy building an application, `error.details.holder` names the operation and the application. While the galaxy host is starting after sleep or creation, `error.details.hostState` is `waking` |
| 429 | `RATE_LIMITED` | The read request limit for the portal was exceeded — [Limits](/docs/infra/database#limits). The pause is in the `Retry-After` header |
| 503 | `APP_DB_TOOL_UNAVAILABLE` | The host is not prepared for database reads or is temporarily unavailable. The response carries a `Retry-After` header |
| 503 | `user_self_deletion_pending` | The key owner is deleting their account on this portal |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **Only SQLite databases are listed.** A file is included if it starts with the SQLite signature. The `-wal`, `-shm` and `-journal` journal files, hidden files and directories whose names start with a dot, and symbolic links are skipped.

## See also

- [Get the database schema](/docs/infra/database/schema)
- [List database backups](/docs/infra/database/backups)
- [Get host preparation status](/docs/infra/database/prepare-status)
- [Application database](/docs/infra/database)
