The restore API: list snapshots, fetch manifests, run scoped restores. Base URL defaults to http://localhost:8080.
CLOUDHOLD_API_KEY to require the X-API-Key header on every endpoint except GET /health. With no key set, bind to localhost or use a trusted reverse proxy.Filter by tenant and platform.
curl -H "X-API-Key: $CLOUDHOLD_API_KEY" \
"http://localhost:8080/snapshots?tenant_id=tenant-acme&platform=github"Items plus the immutable root hash.
curl -H "X-API-Key: $CLOUDHOLD_API_KEY" \
http://localhost:8080/snapshots/snap_20261015_0001Only items the principal is entitled to are restored; the rest are reported in denied.
curl -X POST http://localhost:8080/restore \
-H "X-API-Key: $CLOUDHOLD_API_KEY" -H "Content-Type: application/json" \
-d '{"snapshot_id": "snap_20261015_0001",
"principal": {"id": "user-123", "role": "user"},
"target": "/mnt/restore", "paths": ["repo-a/"]}'Public liveness probe.
curl http://localhost:8080/health| Method | Endpoint | What it does |
|---|---|---|
| GET | /health | Liveness. Public. |
| GET | /snapshots[?tenant_id=..&platform=..] | List snapshots, optionally filtered. |
| GET | /snapshots/<id> | Full manifest: items + immutable root hash. |
| POST | /restore | Scoped restore. Body: snapshot_id, principal{id, role}, target, paths[]. |
| POST | /v1/stripe/webhook | Stripe provisioning webhook (signature-verified; answers 503 until configured). |
| POST | /v1/claim | One-time exchange of a checkout session id for the tenant API key. |
| POST | /v1/signup/free | Free tenant signup (abuse-capped; not a backup plan). |
| GET | /v1/me | Own tenant record: plan, seats, seat_reconciliation_pending, status, provider states. Tenant key required. |
| GET | /v1/providers | Per-platform connection state — not_configured until a real OAuth connection exists. |
| POST | /v1/backup-jobs | Start a backup job. Answers 409 provider_not_configured when the tenant has no provider connection — it never fakes a backup. |
Full reference with request/response examples ships in the repo as
OPENAPI.md.