Backups & PITR
Manage backup schedules, trigger on-demand backups, and generate point-in-time recovery dumps
Manage backup schedules, trigger on-demand backups, view backup history, and generate point-in-time recovery (PITR) dumps. See the backup strategy guide for background and the PITR guide for a walkthrough.
Backups
Trigger backup
| Method | Endpoint | Permission | Description |
|---|---|---|---|
POST | /backup | backup:create | Trigger an on-demand full backup |
Request body:
{
"server_id": "uuid"
}Response (202 Accepted):
{
"backup_id": "uuid",
"status": "running"
}The backup runs asynchronously. Poll the history endpoint to track progress.
List schedules
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /backup/schedules | backup:create | List all backup schedules |
Response:
[
{
"id": "uuid",
"server_id": "uuid",
"server_name": "production-db",
"schedule_cron": "0 2 * * *",
"backup_tool": "mydumper",
"retention_days": 30,
"s3_prefix": null,
"enabled": true,
"last_run": "2026-04-13T02:00:00Z",
"last_status": "completed",
"created_at": "2026-04-01T10:00:00Z"
}
]Create schedule
| Method | Endpoint | Permission | Description |
|---|---|---|---|
POST | /backup/schedules | backup:create | Create a new backup schedule |
Request body:
{
"server_id": "uuid",
"schedule_cron": "0 2 * * *",
"backup_tool": "mydumper",
"retention_days": 30,
"s3_prefix": null
}| Field | Required | Default | Description |
|---|---|---|---|
server_id | yes | — | Server to back up |
schedule_cron | yes | — | Cron expression (e.g. 0 2 * * * for 2 AM daily) |
backup_tool | no | mydumper | Backup tool (mydumper) |
retention_days | no | 30 | Days to retain backups (1–365) |
s3_prefix | no | — | Custom S3 path prefix |
Response (201 Created): The created schedule object.
Update schedule
| Method | Endpoint | Permission | Description |
|---|---|---|---|
PATCH | /backup/schedules/{schedule_id} | backup:create | Update a backup schedule |
All fields are optional. Only provided fields are updated.
{
"enabled": false,
"retention_days": 7,
"schedule_cron": "0 3 * * 0"
}Delete schedule
| Method | Endpoint | Permission | Description |
|---|---|---|---|
DELETE | /backup/schedules/{schedule_id} | backup:create | Delete a backup schedule |
Response: 204 No Content.
List backup history
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /backup/history | backup:create | List backup history |
Query parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
server_id | no | — | Filter by server UUID |
status | no | — | Filter by status (running, completed, failed) |
since | no | — | ISO 8601 start date |
until | no | — | ISO 8601 end date |
limit | no | 50 | Results per page (1–200) |
Response:
[
{
"id": "uuid",
"schedule_id": "uuid",
"server_id": "uuid",
"server_name": "production-db",
"backup_tool": "mydumper",
"status": "completed",
"phase": "complete",
"s3_path": "s3://bucket/backups/tenant/server/2026-04-13/020000/",
"size_bytes": 26000000,
"duration_ms": 4500,
"error_message": null,
"started_at": "2026-04-13T02:00:00Z",
"completed_at": "2026-04-13T02:00:04Z"
}
]Get backup entry
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /backup/history/{history_id} | backup:create | Get a specific backup entry |
Response: A single backup history object (same shape as above).
Point-in-Time Recovery (PITR)
Trigger PITR
| Method | Endpoint | Permission | Description |
|---|---|---|---|
POST | /servers/{server_id}/pitr | backup:create | Trigger a PITR backup |
Request body:
{
"target_time": "2026-04-10T14:30:00Z",
"tables": "mydb.orders,mydb.customers",
"allow_gaps": false
}| Field | Required | Default | Description |
|---|---|---|---|
target_time | yes | — | ISO 8601 timestamp to recover to |
tables | no | all tables | Comma-separated schema.table list. When omitted, all indexed tables are auto-discovered and reconstructed. |
allow_gaps | no | false | Proceed even if there are gaps in the binlog event stream |
Response (202 Accepted):
{
"pitr_id": "uuid",
"status": "running"
}PITR runs asynchronously. Phases progress through: preparing → reconstructing → uploading → complete.
One at a time
Only one PITR can run per server at a time. Triggering a second PITR while one is running returns 409 Conflict.
List PITR history
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /servers/{server_id}/pitr | backup:create | List PITR history for a server |
Query parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
status | no | — | Filter by status (running, completed, failed) |
limit | no | 50 | Results per page (1–200) |
Response:
[
{
"id": "uuid",
"server_id": "uuid",
"server_name": "production-db",
"target_time": "2026-04-10T14:30:00Z",
"tables_filter": null,
"status": "completed",
"phase": "complete",
"s3_path": "s3://bucket/pitr/tenant/server-id/20260410T143000/2026-04-13/141500/",
"size_bytes": 124000,
"file_count": 75,
"duration_ms": 33000,
"error_message": null,
"started_at": "2026-04-13T14:14:30Z",
"completed_at": "2026-04-13T14:15:03Z"
}
]Get PITR coverage
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /servers/{server_id}/pitr/coverage | backup:create | Check the PITR coverage window |
Returns the time range where PITR is possible — based on the oldest and latest indexed binlog events.
Response:
{
"oldest_event": "2026-03-16T01:00:00",
"latest_event": "2026-04-13T14:12:38",
"total_events": 132193,
"available": true
}available is false when the agent is unreachable.
Coverage vs. baselines
The coverage window tells you the binlog event range. PITR also requires a baseline snapshot (from a backup) taken before the target time. If the oldest baseline is from April 1st, PITR to March 20th will fail even if binlog events exist back to March 16th.
Get PITR entry
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /servers/{server_id}/pitr/{pitr_id} | backup:create | Get details of a specific PITR run |
Response: A single PITR history object (same shape as the list response).