Docs

Database restores API

Read the recovery window, start a point-in-time database restore, follow its progress and undo the latest completed restore.

Updated October 31, 2026
On this page
  1. Read the recovery window
  2. Start a restore
  3. Undo the latest restore
  4. Handle errors and retries

These routes recover a project's PostgreSQL database. They do not roll back its application release or restore files, KV data or account settings. Read Backups and restore before starting a recovery.

GET/projects/{name}/restoresRecovery window, eligibility and the 20 newest restores
POST/projects/{name}/restoresQueue a restore to a Unix timestamp
POST/projects/{name}/restores/{id}/undoSwitch back to the database the latest restore replaced

Use an account API token. Project members can read status; only the owner or an admin can start or undo recovery. Use the full project name from List projects.

Read the recovery window

Terminal
curl https://api.fortly.com/projects/my-app-ada/restores \
  -H "Authorization: Bearer $FORTLY_TOKEN"
FieldMeaning
databaseWhether the project has a managed database.
eligibleWhether the owning account's plan or current Free offer permits restores.
can_restoreWhether the caller is the owner or an admin. Check this separately from eligibility.
service_okWhether the recovery service's catalogue is fresh. Do not start while false.
retention_daysThe recovery retention, currently 7 days.
window{ "from": ..., "to": ... } in Unix seconds, or null before a recovery window exists. Both bounds are inclusive.
pointsDaily backup timestamps inside the window. Targets are not restricted to these timestamps.
offer_untilFree offer's exclusive cutoff, or null for paid accounts or an inactive offer.
restores_left_todayRemaining Free allowance in the preceding 24 hours, or null when no Free offer applies. The field name does not imply a midnight reset.
restoresUp to 20 restores, newest first.
undoableThe latest restore id that can still be undone, or null.

The Free offer includes December 1, 2026, UTC: its cutoff is December 2 at 00:00 UTC (1796169600). It allows one non-failed restore per project in a rolling 24-hour window. Pro and Max remove that allowance. Undo does not consume an additional restore or refund the first one.

Start a restore

Choose target_at from the server's current window. Convert the intended date and timezone to Unix seconds, review the project and target, then submit:

Terminal
# Set TARGET_AT to the Unix timestamp you reviewed, within window.from and window.to.
curl -X POST https://api.fortly.com/projects/my-app-ada/restores \
  -H "Authorization: Bearer $FORTLY_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"target_at\":$TARGET_AT}"

Answers 202 with the restore record. This means accepted, not complete. Poll the GET route and find the returned id; the console checks every three seconds while a restore is active.

StateWhat is happening
queuedWaiting for the recovery service.
restoringRebuilding the database from its backups.
stagedRebuilt; waiting for the project to switch to it.
doneThe project is using the restored database.
failedRecovery failed; detail explains why. The current database remains in use.
undoneUndo switched the project back to its previous database.

Records include id, target_at, state, detail, created_at, started_at, finished_at and undone_at. Nullable timestamps have not occurred yet. Internal database names and the requesting account's id are not returned.

At switch-over, data written after the selected moment is replaced, including writes made while recovery was running. Pause writers first if necessary. A database restore does not change the deployed code; verify schema compatibility afterwards.

Undo the latest restore

Read undoable again before submitting. Review the loss of access to writes made since the restore, then call:

Terminal
curl -X POST https://api.fortly.com/projects/my-app-ada/restores/$RESTORE_ID/undo \
  -H "Authorization: Bearer $FORTLY_TOKEN"

The previous database is retained for seven days after completion. Undo normally returns 200 with the updated record; it can return 204 if the switch completed but the record could not be read back. Refresh status after either response. Undo is available for an eligible retained restore even after the Free offer expires; it does not require a new paid-plan entitlement.

Only the latest completed restore can be undone, and Undo itself is not a repeatable toggle. Check the current undoable value instead of retrying an old id blindly.

Handle errors and retries

StatusWhat to do
400Send an integer target_at within the current server window.
402Upgrade: the Free offer has ended for this account.
403Ask the owner or an admin to perform the operation.
404Verify project access and whether it has a database.
409A restore is already active, no recovery window exists yet, or the requested Undo is no longer eligible. Refresh status.
429The Free project's rolling 24-hour allowance is used. Wait or upgrade.
503The recovery catalogue is unavailable or stale. Wait and refresh status.

There is no idempotency key. If a POST response is lost, read the restore list before starting another request. A second active restore is refused, rather than put behind the first one in a queue.

Something missing or unclear? Tell us and we will fix the page.© 2026 Fortly