Skip to main content

Disaster Readiness API

For the dashboard flow (enable protection, Validate now, Activate as live, and how Disaster Ready is shown), start with Disaster Readiness.

These endpoints share the dashboard's account permissions and DR configuration services. They cover inventory, setup, isolated validation, status and activation admission—not proof of completed live recovery. Availability of an endpoint or successful preparation does not certify data recoverability. The feature remains subject to regional qualification. Availability of an API is not a completed product release.

All paths below use /api/public/v1. Account-wide calls require user authentication, not environment tokens. Members only see permitted environments; account admins configure protection. Internal roles do not bypass membership.

EndpointOAuth scopesMCP tool
GET /disaster-readiness/sourcesquave:readlist-disaster-readiness-sources
GET /disaster-readiness/configurationsquave:readlist-disaster-readiness-configurations
POST /disaster-readiness/configureBoth quave:write:config and quave:write:deployconfigure-disaster-readiness
POST /disaster-readiness/validatequave:write:deployvalidate-disaster-readiness-now
POST /disaster-readiness/discard-activationBoth quave:write:deploy and quave:write:dangerousdiscard-disaster-readiness-activation
POST /disaster-readiness/resetBoth quave:write:deploy and quave:write:dangerousreset-disaster-readiness

MCP tool-mode keys must authorize the specific tool. Scope-mode keys must have all its required scopes; selecting an unrelated tool does not grant DR access.

Inventory and status​

Both GET endpoints accept accountId, optional after, and limit (1–100, default 50). Responses contain items and optional nextCursor; pass that cursor as after for the next page.

Sources report volume eligibility, unsupported reasons, eligible destinations and suggested settings. A protected source also reports target (appEnvId, appId, appName, environmentName) once its target app env exists: the warm standby, or the recovered environment after activation. Eligibility is not readiness. Configurations report safe settings, generation, operation references and readiness evaluated at request time. Unknown, expired or failed evidence must not be interpreted as Ready. Provider credentials, signed URLs, private engine settings and execution leases are not returned.

Bulk configuration​

Review selection, destination, mode, schedules, costs and warnings before calling:

{
"accountId": "ACCOUNT_ID",
"common": {
"destinationRegion": "ELIGIBLE_REGION",
"mode": "cold"
},
"items": [
{
"sourceAppEnvId": "SOURCE_ENV_ID",
"requestId": "stable-request-reference",
"expectedGeneration": 0
}
]
}

Select 1–100 distinct environments. Each item may include overrides for common settings. Supported settings are destinationRegion, mode (cold/warm), storageCredentialId, snapshotIntervalMs, validationIntervalMs, rpoTargetMs, rtoTargetMs, and sameRegionAcknowledged. Intervals/targets are milliseconds, from one minute to 30 days; snapshot intervals must also map exactly to a supported snapshot schedule. Omitted values use the dashboard defaults. Explicit null storageCredentialId selects platform storage; omission inherits source storage. Same-region protection requires explicit acknowledgment and remains limited.

Each item can include target with the recovered names: envName, plus appName for databases (which always restore into a new app; other apps can set createNewApp: true with an appName). Warm mode prepares the recovered destination at setup, so warm items must include target. Cold items may include it too: the names are saved and returned as plannedDestination in configuration status, so activation can pre-fill them (activation still sends its own target). Editing cold protection without target keeps the saved names.

{
"sourceAppEnvId": "SOURCE_ENV_ID",
"requestId": "stable-request-reference",
"target": { "envName": "recovered", "appName": "orders-db-recovered" }
}

The response is HTTP 200 with per-item results: sourceAppEnvId, success, and either configurationId, operationId, generation, phase or a safe error. Successful configuration queues asynchronous preparation and can incur storage/transfer/compute costs. It does not mean the data is restored, Ready, or live. Inspect each result and poll configuration status.

For edits, pass the current expectedGeneration. Reuse the same item requestId and payload after an uncertain response; changing the payload under the same reference is rejected. Retry failed items separately after correcting the cause. Do not regenerate references simply because a response timed out.

This endpoint does not disable protection, promote a standby, reconnect apps, change DNS, expose database credentials, or offer a dryRun parameter.

Validate now​

An account administrator can request an isolated test of the configuration's retained data in its configured destination. Initial enrollment must have completed and no other recovery operation may be active.

{
"accountId": "ACCOUNT_ID",
"configurationId": "CONFIGURATION_ID",
"expectedGeneration": 2,
"requestId": "stable-validation-reference"
}

The response contains configurationId, operationId, generation and phase. It confirms a journaled request, not restored data, cleanup completion or Disaster Ready. Poll configuration status and the validation evidence for the outcome.

This can allocate temporary billable resources. It does not switch source traffic, start the customer's application, promote a live target, or reset the normal snapshot/validation cadence. Admission uses retained configuration and does not require contacting the source region.

Inactive validation bounds engine CPU/memory to the regional standby capacity without resizing its VM. Successful validation is not live compute proof: activation must separately complete and verify the owned VM's vertical resize and 50% baseline. A validation resource/startup failure remains a failed check.

After an uncertain reply, retry the exact same request ID and generation. Authorization is checked again, but a committed operation is returned rather than re-created. A changed generation or reused reference for another operation is rejected. New requests use a fresh reference after refreshing status. Additional execution fields, actor overrides and dryRun are not accepted.

Retained points and activation​

Status may also include warmValidationOperationId for check-only eligibility. A fully cleaned failed check can permit another isolated check while recovery remains blocked. The server verifies retained cleanup and receiver ownership; this hint is neither successful data validation nor Disaster Ready. New clients prefer this hint for checks; the recovery hint remains separate. A historical failed check no longer blocks recovery permanently after its cleanup is verified and a later check succeeds for the protected point. A failed latest check, pending operation, or unverifiable cleanup still blocks recovery; normal activation evidence and custody checks remain mandatory.

Status may include warmRecoveryOperationId matching activeOperationId when warm synchronization is settled and may be taken over for recovery. This is an advisory action hint, not Disaster Ready evidence or permission. Activation checks ownership, lease and pending effects again atomically; a new sync pass may make the hint stale. For warm mode with an established validation schedule, this same settled-owner hint also enables requesting another isolated check of the protected point. Admission serializes it with append, resize and recovery; it never permits concurrent effects. The original receiver stays activeOperationId while the returned operationId identifies the individual check request. A fresh request gets a fresh validation execution/history even for the same point; retrying that request cannot replay an older check as new evidence. Manual checks preserve both schedule timestamps. Scheduled checks advance from their due timestamp and skip missed intervals rather than launching a catch-up batch. Neither admission nor schedule initialization changes Disaster Ready status.

GET /disaster-readiness/points accepts accountId, configurationId, optional after and limit (1–100). Requires read capability and account membership; member environment restrictions still apply. Response includes generation, items and nextCursor. Each item has selectedOperationId, pointId, cutoffAt and availabilityRequiresVerification: true. These are candidates, not proof that objects still exist or are readable. Pagination is not chronological. For warm protection, the selectable item is the configuration-owned validated point from the original receiver journal, which may be an incremental point rather than the initial seed. Missing, ambiguous or mismatched custody yields no warm item; an unfinished newer append is not substituted. This listing does not grant readiness.

When the operation's frozen source contract matches the protection contract, retainedSizing exposes its replica count, optional zClouds, per-replica CPU limits/requests (cpu, cpuRequest, in cores), memory limits/requests (memoryMb, memoryRequestMb, in decimal MB), and volumeCapacities (Kubernetes quantities). Missing or invalid sizing is omitted, not replaced with current source values or defaults. No source-region contact is needed. This is a sizing preview, not a VM reservation, full database topology specification or capacity qualification. Do not submit this preview as activation resource overrides.

When a source engine cannot be activated as live yet, configuration status includes activationUnavailableReason: restore validation remains available, but new Activate-as-live requests are rejected before ownership or target changes. Do not treat Ready validation as native live-handoff support.

POST /disaster-readiness/activate requires account admin permission and both quave:write:deploy and quave:write:dangerous capabilities. Send:

{
"accountId": "account-id",
"configurationId": "configuration-id",
"expectedGeneration": 2,
"requestId": "stable-activation-request-id",
"selectedOperationId": "operation-from-points-list",
"pointId": "<64-character-point-hash-from-points-list>",
"cutoffAt": "2026-09-11T10:00:00.000Z",
"target": {
"envName": "recovered",
"createNewApp": true,
"appName": "Recovered app"
},
"writerSafetyAcknowledged": true
}

Select an explicit point and explain its cutoff and possible data loss. Obtain explicit acknowledgment of double-writing risk if the source cannot be fenced; source unavailability does not itself prevent submitting the request. The server owns actor/audit identity and validates the retained configuration and point. Before allocation, the worker verifies retained objects and historical keys. It never silently substitutes another point. Billable resources may be allocated.

For warm protection, setup already created the recovered app and environment. Configuration status returns their names as warmDestination (envName, createNewApp, and appName when a new app was created). Send exactly those names in target; different names are rejected before any work starts. Cold activation chooses the names at activation time.

Retry the same payload and request ID after an uncertain response. A successful response is an operation journal receipt, not completed recovery. Poll configuration status and inspect operation evidence. This endpoint does not switch DNS or start the customer application. It has no dry-run parameter; use isolated validation for a check. Live ownership handoff and engine-specific recovery are still being qualified; do not treat API availability as a completed product release.

Discard an unfinished activation​

An account administrator can discard an activation that has not become live, for example one stuck in progress or started with the wrong destination names. This is the API equivalent of the dashboard Discard action. An activation in progress blocks reset and new activations until it is discarded and cleaned up, except one that keeps failing before promotion (see below): Reset is allowed then.

POST /disaster-readiness/discard-activation requires account admin permission and both quave:write:deploy and quave:write:dangerous capabilities. Internal roles do not bypass account membership. Send:

{
"accountId": "ACCOUNT_ID",
"configurationId": "CONFIGURATION_ID",
"operationId": "ACTIVE_ACTIVATION_OPERATION_ID",
"expectedGeneration": 2,
"requestId": "stable-discard-request-id",
"discardAcknowledged": true
}

operationId is the configuration's activeOperationId while the activation is in progress. discardAcknowledged must be the literal true and represents the user's explicit acknowledgment that the unfinished recovery target will be discarded.

The server rejects the request when the activation already succeeded, is handing over live ownership, or no longer matches the configuration generation. It also rejects an activation that has not reached promotion yet (promoting or starting phase), because its recovery target is still being prepared, unless a cold activation keeps failing there: after 6 consecutive failed steps (about 15 minutes of retries) it can be discarded, which removes the recovery target it created and returns the configuration to protection. A warm activation that keeps failing before promotion is ended with Reset. Status reports canRequestDiscard: true once a discard is accepted. Admission moves the operation to cleanup and revokes the worker lease in one transaction; the response is an operation journal receipt (operationId, configurationId, generation, phase), not cleanup completion. Poll configuration status until cleanup finishes before resetting or activating again. Retry the same payload and request ID after an uncertain response. The live source and any target that already became live are never touched. There is no dryRun parameter.

Completed data or native database activation​

Configuration status may include activationResult after the atomic completion of a generic cold activation or an accepted native PostgreSQL/Redis activation. It contains only operationId, targetAppEnvId, targetAppId, pointId, the selected cutoffAt, and completedAt, plus engine for a verified native database completion (postgresql or redis). Generic-volume completion omits engine. targetAppId is the recovered app. Clients can use it to show reconnection guidance rather than ask users to deploy a database that recovery already started. This is a historical data handoff receipt, not current workload health, traffic migration or renewed DR readiness. Missing metadata is not inferred from a target ID or consumed protection.

For generic recovery, the recovered environment keeps its original persistent-volume roles. Configure the application image and secrets, address source-writer safety, then deploy explicitly and verify the application before reconnecting clients or changing DNS. Activate and validate new protection for the new live environment.

For native PostgreSQL/Redis recovery, completion requires database and public TLS endpoint verification plus ownership handoff. The recovered environment exposes the tested database endpoint (Redis uses rediss://); completion does not reconnect application clients or prove their health. Reconnect and verify clients explicitly, then establish new protection. Native recovery is still being qualified.

Temporary validation target cleanup​

Configuration status may include activeOperation.validationCleanup while a validation operation waits for temporary target retirement. It contains only observedAt, an optional retentionUntil, and retentionPending. These are advisory observations, not evidence of final deletion or Disaster Ready status. A retention deadline is the earliest policy-permitted deletion time, not a completion guarantee. Retained storage may continue to incur costs. Cleanup continues automatically. Parking alone never releases ownership or recovery-point holds.

After verified removal of the isolated test data and compute, the server may atomically transfer cleanup to an independently leased obligation and release the configuration operation lock. A new explicit recovery uses a different target; old cleanup cannot modify it. Disk retention and held snapshot dependencies remain protected until their own verified completion.

Both configuration status and source inventory can include pendingCleanup, independent of activeOperation and including earlier configuration generations: pendingCount, retainedDiskCount, retryingCount, and optional earliestRetentionUntil. Counts cover only the caller-authorized sources. A retained-disk count is conservative; zero means provider cleanup was confirmed, not that database/full-path validation succeeded. Pending validation acceptance remains visible after resources are removed. The earliest retention deadline is advisory, not a deletion promise. These fields never establish Disaster Ready.

Selected activation cutoff​

During activation, activeOperation.cutoffAt is the canonical UTC timestamp of its explicitly selected, pinned recovery point. activities[].cutoffAt records that same cutoff on the activation's history entries, including after failure or completion. These optional fields are omitted when unavailable or invalid; clients must not replace a missing selected cutoff with a newer snapshot. The dashboard displays them in browser-local date/time, separately from the activity's execution time. The selected cutoff is not proof of Live completion.

Validation scheduling prerequisite​

Configuration status includes validationScheduleEstablished. A false value means initial setup has not yet established a valid validation schedule; clients should explain this before offering a new Validate now request. true is not proof of successful enrollment, permission to mutate, or Disaster Ready: admission still checks the current successful enrollment, ownership and operation lock. Preserve an unconfirmed request's idempotency reference when retrying it. Recovery point selection has its own availability checks and is not gated by this flag.

Reset​

An account administrator can wipe Disaster Readiness for one environment or the whole account and start over. This is for stuck or broken protection, not for turning off a healthy live recovered environment.

POST /disaster-readiness/reset requires account admin permission and both quave:write:deploy and quave:write:dangerous capabilities. Send:

{
"accountId": "ACCOUNT_ID",
"scope": "environment",
"confirmationName": "exact-environment-name",
"sourceAppEnvId": "SOURCE_ENV_ID"
}

For the whole account, use "scope": "account" and the exact account name as confirmationName. Do not send sourceAppEnvId on an account reset.

The server deletes Disaster Readiness configuration records and leftover recovery destinations still owned by those settings. It does not delete the live source or a destination that already became live. The response is the wipe counts (configurations, destinations), not a new protection setup. There is no dryRun parameter.

Reset first fences protection work and retires its exact owned compute, including allocations that have not created a recovery environment yet. While provider cleanup is pending, retry the same reset: configuration and operation records remain available instead of reporting a successful wipe. Compute cleanup retains data disks under their existing retention policy; it does not erase the source, independent live destinations, or other targets in the regional pool.

Recovery destination names​

Activation requires target: { envName, createNewApp, appName }, using the same destination rules as Snapshots → Create new environment. Every activation sends envName. Database recovery and createNewApp: true require appName and create a new app; application recovery uses the source app unless createNewApp: true is selected. Names are trimmed. Omitting target is rejected.

The exact destination payload is part of the idempotency request: retry it unchanged. App metadata is frozen at admission, but the app is created and the recovered environment is named/reparented atomically only after verified Live handoff. The destination remains in the same account. activationResult.targetAppId identifies the recovered app on every current result. The region, disk, compute, environment ID, runtime slug, database name, endpoints and source data are not changed by the naming options. DR does not trigger an ordinary snapshot restore or build/deploy, and source environment secrets and hosts are not copied.

Snapshot cutoff semantics​

Warm readiness cutoffs and RPO use retained destination evidence, not newer source snapshot notifications. When the source starts a new full backup chain, a warm standby must receive that full chain before it can follow new snapshots again; while the recovery point is past the RPO target for that reason, readiness.reason is chainRollover instead of rpoExceeded. The state stays needsAttention, and cutoffAt/recoveryPointAgeMs still report the real gap. Likewise, while a warm standby is visibly applying a large source change (for example a table rebuild that produced a multi-GB incremental), readiness.reason is catchingUp instead of rpoExceeded, with the same needsAttention state and real gap. Both reasons fall back to rpoExceeded 12 hours past the target, or when the standby stops making progress. A warm point is selectable only when it matches current protected custody, including increments in an active replacement stream. Listing a candidate still does not replace activation-time verification.

Warm standby shape​

A warm configuration reports standby with the inactive shape its standby runs on and why:

  • shape: "standard": the default standby (1/8 CPU baseline).
  • shape: "seedBoost", reason: "catchingUp": a temporary larger standby for a large first copy. It stays until the standby has applied the first copy, the changes that arrived meanwhile, and two consecutive changes well inside the snapshot interval.
  • shape: "sustained", reason: "standardTooSlow": recent changes took more than a third of the snapshot interval to apply on the default standby, so the standby keeps a full CPU baseline (higher standby cost). It returns to standard only after a sustained quiet period.

caughtUp, lastApplySeconds and lastApplyBytes show the latest measurements. readiness.warnings includes sustainedStandby or seedBoost while one of those shapes is in use. A shape change restarts the standby VM between changes; none of these shapes is the live shape.

The dashboard additionally offers cold Choose snapshot to recover, backed by the existing environment snapshot catalog and exact-point isolated validation. This UI workflow does not change the public activation request shape or bypass engine support. After validation, its retained operation/point/cutoff can be selected through the existing activation contract. UI timestamps are browser-local; API timestamps remain canonical UTC.

After a verified native PostgreSQL handoff, the normal replica collector registers the existing ready runtime in the ordinary environment history. The environment then shows Running, actual replicas and CPU/memory metrics; Live on the DR card remains the historical activation result. Registration does not rebuild, restart, copy or replace the retained warm disk. Existing completed PostgreSQL handoffs are reconciled the same way. A handoff receipt alone never creates a Running status, and later failed/unready replicas remain visible through normal runtime telemetry. Client reconnection is still a separate action.

The environment does not use a recovery-specific Live runtime status. Its Running/Stopped state and replicas come from the ordinary environment records; the DR card keeps the historical activation outcome. Native PostgreSQL recovery also uses the regular database status/host reconciliation, including internal connection hosts. No restart or second restore is needed to register them.

Cold recovery and Create environment from recovery point share snapshot-chain selection, restore-package materialization and recovery destination creation. DR adds pinned-point, lease, placement and ownership checks around that core. Warm activation keeps its existing disk rather than invoking restore-on-deploy again.