Backups and restores
Create backup policies, inspect runs, and restore data.
The Backups API manages a project's backup policies (what to back up and on what schedule), the runs
they produce, and the restores that put a run's data back. It pairs with the
Backup Destinations API (where backups are stored) — in the dashboard this
is the project's Backups tab, and from the terminal it's the openship backup
command.
The routes are split across a few prefixes: policy creation and listing are project-scoped
(/api/projects/:projectId/backup-policies), while an existing policy, run, or restore is addressed by
its own id (/api/backup-policies/:id, /api/backup-runs/:id, /api/backup-restores/:id). The inbound
POST /api/webhooks/backup trigger lives on its own unauthenticated prefix. Available on both self-hosted
and cloud instances; the project-scoped policy and run routes proxy to Openship Cloud for cloud projects.
Create a backup policy
A policy binds a project (optionally a single service) to a destination,
plus an optional schedule and retention rules. The request body is read inline (there is no TypeBox schema
file for this module); destinationId is the only required field.
const result = await ship.backups.createPolicy("proj_123", {
destinationId: "dst_abc",
cronExpression: "0 3 * * *",
retainCount: 7,
});
console.log(result);curl -X POST "$OPENSHIP_URL/api/projects/proj_123/backup-policies" \
-H "Authorization: Bearer $OPENSHIP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"destinationId":"dst_abc","cronExpression":"0 3 * * *","retainCount":7}'Prop
Type
Update a policy
PATCH accepts only the allow-listed fields below — projectId, serviceId, and createdBy cannot be
changed, and the webhook token is controlled through the enableWebhook / rotateWebhookToken flags rather
than written directly. Unknown fields are dropped.
PATCH /api/backup-policies/:policyIdProp
Type
Trigger a backup manually
const run = await ship.backups.run("policy_123");
console.log(run);curl -X POST "$OPENSHIP_URL/api/backup-policies/policy_123/run" \
-H "Authorization: Bearer $OPENSHIP_TOKEN"Kicks off a run for the policy immediately. Returns { data: { runId } } — follow it with the run stream.
const result = await ship.backups.run("bkp_abc");
console.log(result);curl -X POST "$OPENSHIP_URL/api/backup-policies/bkp_abc/run" \
-H "Authorization: Bearer $OPENSHIP_TOKEN"Protect a run from retention
Retention prune drops runs past a policy's retainCount / retainDays. Lock a run to keep it, or release
the lock so it becomes eligible again.
POST /api/backup-runs/:runId/protectProp
Type
Stage and apply a restore
Restoring is two steps. Prepare stages the restore and returns a one-time confirmationToken; apply
echoes that token back to actually run the (destructive) restore. This guards against accidental
re-submits.
POST /api/backup-runs/:runId/restore/prepareProp
Type
The response is { data: { restoreId, confirmationToken } }. Pass both to apply:
POST /api/backup-restores/:restoreId/applyProp
Type
Cancel a staged or in-flight restore with POST /api/backup-restores/:restoreId/cancel
(openship backup restore cancel rst_123).
Live progress (SSE)
Both runs and restores expose a Server-Sent Events channel that emits a snapshot event with the current
row immediately, then live transition / progress events, and a final complete event. Terminal
statuses are succeeded, failed, cancelled, and server_error; the stream closes once one is reached
(or right away if the row is already terminal).
GET /api/backup-runs/:runId/stream
GET /api/backup-restores/:restoreId/streamTrigger a backup by webhook
POST /api/webhooks/backup is the one unauthenticated route — the per-policy webhook token is the
credential, sent as a bearer header (enable it via enableWebhook on the policy). There is no request body.
On success it returns { data: { runId } }; every failure returns an opaque 404 so a probe can't tell a
bad token from a disabled policy. The route is rate-limited to blunt trigger-flood abuse.
POST /api/webhooks/backupcurl -X POST "$OPENSHIP_URL/api/webhooks/backup" \
-H "Authorization: Bearer $POLICY_WEBHOOK_TOKEN"Errors
400 — invalid cron expression
createPolicy / updatePolicy validate the cron up front so an unparseable schedule can't silently disable
the policy. Fix the expression (e.g. 0 3 * * *) and retry.
400 — confirmationToken is required
Applying a restore without the exact token returned by restore/prepare is rejected. Re-run prepare to get
a fresh token if you've lost it.
404 on a per-resource route
The :id doesn't belong to your organization (or was deleted) — the same opaque 404 the webhook returns
for a bad token. List runs with GET /api/projects/:projectId/backup-runs to get valid IDs.
Operations
| Operation | SDK | REST API |
|---|---|---|
| Stream backup execution progress. | backups.streamRun(id, options?) | GET /api/backup-runs/:runId/streambackup_destination:backup_run:read |
| Stream restore progress. | backups.streamRestore(id, options?) | GET /api/backup-restores/:restoreId/streambackup_destination:backup_restore:read |
| List backup policies for the requested source. | backups.listPolicies(id) | GET /api/projects/:projectId/backup-policiesproject:write |
| Create a backup policy and retention configuration. | backups.createPolicy(id, input) | POST /api/projects/:projectId/backup-policiesproject:write |
| List recorded backup runs using typed filters. | backups.listRuns(id, input?) | GET /api/projects/:projectId/backup-runsproject:write |
| Change a backup policy. | backups.updatePolicy(id, input) | PATCH /api/backup-policies/:policyIdbackup_destination:backup_policy:write |
| Remove a backup policy. | backups.removePolicy(id) | DELETE /api/backup-policies/:policyIdbackup_destination:backup_policy:write |
| Trigger a policy’s backup now. | backups.run(id, input?) | POST /api/backup-policies/:policyId/runbackup_destination:backup_policy:write |
| Read a backup run and its result. | backups.getRun(id) | GET /api/backup-runs/:runIdbackup_destination:backup_run:read |
| Protect or unprotect a run from retention pruning. | backups.protectRun(id, input?) | POST /api/backup-runs/:runId/protectbackup_destination:backup_run:write |
| Stage and validate a restore without applying it. | backups.prepareRestore(id, input?) | POST /api/backup-runs/:runId/restore/preparebackup_destination:backup_run:admin |
| Read a restore session and its confirmation requirements. | backups.getRestore(id) | GET /api/backup-restores/:restoreIdbackup_destination:backup_restore:read |
| Apply a prepared restore using the required confirmation. | backups.applyRestore(id, input) | POST /api/backup-restores/:restoreId/applybackup_destination:backup_restore:admin |
| Request cancellation of a restore. | backups.cancelRestore(id) | POST /api/backup-restores/:restoreId/cancelbackup_destination:backup_restore:admin |