Application Backups

Application backups

Capture a point-in-time copy of a running app — its managed database, its content volume, or both — and restore it later with a single call. Backups are handled entirely by Ngris: nothing to install, no dump scripts to schedule, no bucket to manage. You run one backup on demand or leave a schedule to run them for you.

A backup is one of three kinds, and what it captures depends on what your app actually has:

  • Database (database) — a gzipped SQL dump of the app's managed database. Applies to any managed app with a bound managed database.
  • Content (content) — a gzipped tar of the app's persistent content volume. Applies to apps that have one — today, Managed WordPress.
  • Full (full, the default) — both the database and the content volume in one backup, whichever the app has.
Backups follow the app's resources, not just its files. A database backup needs a managed database in the ready state; a content backup needs a content volume. A plain static site has neither, so it has nothing to back up here — static content is versioned by its deploys instead.

Backups are a paid-plan feature, gated by granular per-operation entitlements — see Plan availability.

See your backups

Open your app's detail page and go to the Backups tab. Each backup shows its kind (database / content / full), whether it was manual or scheduled, its status (pendingrunningcompleted, or failed), the captured size, and when it was created. A backup that has been restored also shows a restore status.

API

curl "https://api.ngris.com/v1/applications/{uuid}/backups" \
  -H "X-API-KEY: <your_api_key>"

The response lists every backup under items, reports your plan capabilities and the retention_max cap, and includes the current schedule (or null). If your plan grants none of the backup features, locked is true. See the API reference for the full shape.

Take a backup on demand

From the Backups tab, click Back up now and choose the kind — Full by default. Ngris queues the job; the new backup appears immediately as pending and moves to completed when the dump and upload finish. Only one backup runs at a time per app.

API

curl -X POST "https://api.ngris.com/v1/applications/{uuid}/backups" \
  -H "X-API-KEY: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "full" }'
What can go wrong. A database backup on an app with no ready managed database, or a content backup on an app with no content volume, is rejected (400). Requesting a kind your plan does not grant returns 403. If a backup is already in progress, the request returns 409 — wait for it to finish.

Restore a backup

⚠ Restore is destructive. Restoring overwrites the app's current database and/or content volume with the contents of the backup. There is no undo — anything written since the backup was taken is replaced. In the dashboard, restore is behind an explicit confirmation. Take a fresh backup first if you might want to come back.

From the Backups tab, pick a completed backup and click Restore. Ngris restores the captured artifacts into place; the backup's restore_status tracks progress (restoringrestored, or failed).

API

curl -X POST \
  "https://api.ngris.com/v1/applications/{uuid}/backups/{backup_uuid}/restore" \
  -H "X-API-KEY: <your_api_key>"

The call returns 202 with { "status": "restoring" }. Only a completed backup can be restored (409 otherwise), and the restore is gated by the matching per-kind entitlement — database restore for a database backup, content restore for a content backup (403 if your plan lacks it).

Download a backup

You can pull a completed backup's raw artifact down to keep an off-platform copy. Each artifact streams as a gzip file — the SQL dump for the database, the tar for the content volume.

API

# database dump (default)
curl -L -o backup-db.sql.gz \
  "https://api.ngris.com/v1/applications/{uuid}/backups/{backup_uuid}/download?artifact=database" \
  -H "X-API-KEY: <your_api_key>"

# content volume
curl -L -o backup-content.tar.gz \
  "https://api.ngris.com/v1/applications/{uuid}/backups/{backup_uuid}/download?artifact=content" \
  -H "X-API-KEY: <your_api_key>"

The artifact query selects database (the default) or content. The response is Content-Type: application/gzip, served as an attachment.

Scheduling & retention

Instead of remembering to click Back up now, leave a schedule running. A schedule runs one backup of a chosen kind daily or weekly at a fixed UTC hour, and keeps the most recent N backups — older ones are pruned automatically.

  • Frequencydaily or weekly.
  • Hour — an hour of the day in UTC (023); pick a low-traffic window.
  • Kinddatabase, content, or full, same as an on-demand backup.
  • Retain count — how many scheduled backups to keep. It is clamped to your plan's retention cap (backup_retention_max); once the count is exceeded, the oldest scheduled backups are deleted.

API

curl -X PUT \
  "https://api.ngris.com/v1/applications/{uuid}/backup-schedule" \
  -H "X-API-KEY: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "kind": "full",
    "frequency": "daily",
    "hour_utc": 3,
    "retain_count": 7
  }'
Enabling a schedule needs the schedule entitlement. Turning a schedule on requires the application_backup_schedule entitlement (403 without it) — but a downgraded account can always turn one off. If an account later loses the entitlement, its automatic schedules are disabled for it.

Plan availability

Backups are a paid-plan feature. Rather than a single on/off switch, each operation has its own entitlement, so a plan can grant, say, backups without restore, or database backups without content backups:

  • application_db_backup — take a database backup.
  • application_db_restore — restore a database backup.
  • application_content_backup — take a content-volume backup.
  • application_content_restore — restore a content-volume backup.
  • application_backup_schedule — enable automatic scheduled backups.
  • backup_retention_max — the numeric cap on how many backups a schedule retains.

The GET backups response reports these as a capabilities object (which operations are actually available for this app on your plan) plus retention_max; locked is true when your plan grants none of them. The dashboard uses the same signals to show or lock each button.

Iris