---
title: "Restore a backup over its app, then restart it"
method: POST
path: "/backups/{id}/restore"
tags: ["Platform"]
---

# Restore a backup over its app, then restart it

`POST /backups/{id}/restore`

## Request

- Base URL: `https://api.imprezahost.com/v1`
- URL: `https://api.imprezahost.com/v1/backups/{id}/restore`
- Auth: API key in header `X-API-Key` and API key in header `X-API-Secret`

Every chunk's SHA-256 is verified before anything on the server is
touched. The data being replaced is then moved aside — not deleted —
into `data.replaced-<timestamp>`, and the restored files land in the
same `data` directory, so a running container's bind mount stays
valid. The app is restarted once the files are in place.

The displaced copy keeps using disk until
`POST /backups/{id}/discard-previous` removes it; the job's
`replaced_path` names it.

**Naming a destination copies the app instead of restoring it**,
which is how an app moves between servers. Deploy the same app on
the other server first, then pass its id as
`target_deployment_id`. The app the backup came from is not
touched at all — it keeps running, so the copy can be tested
before anything is switched off.

Two rules the destination has to satisfy, and both answer with the
reason rather than a bare refusal: it must be running, and it must
be the same app. "Same app" means the catalog name for a catalog
app, and the same SOURCE — the same image or the same repository —
for a custom deployment, whose name cannot be compared because one
customer cannot have two custom deployments sharing a name.

The domain does not travel. The copy keeps its own hostname, and
repointing DNS is the customer's move when they are ready. Neither
does the `.onion`: the archive carries the hidden-service key, but
it is only put back over the app it came from — two Tor instances
publishing one key is the service flapping, not a spare.

Credentials do travel. A copy takes the source's variables, minus
the ones that are the destination's own address, and the
destination's containers are recreated rather than restarted —
otherwise the copied database would refuse the destination's own
generated password.

## Path parameters

- `id` string, required

## Request body

- object
  - `target_deployment_id` string: Copy into this app instead of restoring over the original. Must be running, the same app, and on the same account. Omit to restore over the app the backup came from.

## Response `202`

Restore (or copy) job queued

## Other responses

- `401`: Invalid or missing API credentials
- `404`: Resource not found
- `409`: Not a completed backup, a job is in flight, the manifest is unreadable, or the destination is a different app (`APP_MISMATCH`) or not running (`TARGET_NOT_RUNNING`)

---

[API](https://skmtc.dev/imprezahost/apis/impreza-host-public-api.md) · [All operations](https://skmtc.dev/imprezahost/apis/impreza-host-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/imprezahost/apis/impreza-host-public-api/revisions/db86511f604f?raw)
