# Cluster Backups API

Backups are automatic copies of a cluster's data, taken on a schedule you choose and kept for 7, 14 or 30 days in 1 to 3 regions. You can restore a backup to a new cluster in any region, or onto the cluster it was taken from.

WARNING

Backups are billed for the storage they use and the bandwidth it takes to upload them, as described in Billing. To turn them on, you need a payment method or prepaid credits on your account.

# Workflow

Here's a typical sequence of API calls you'd perform when using this API:

  1. Get the backup settings to see the estimated monthly cost of a schedule at your cluster's data size.
  2. Turn backups on, with the schedule, retention and regions you want.
  3. List the backups the cluster keeps.
  4. Restore a backup to a new cluster or onto this cluster, then poll the cloning operation that runs the restore until it succeeds.

# Get backup settings

This endpoint returns the cluster's backup settings, when the next backup is due and what these settings are estimated to cost each month:

curl -X GET --location "https://cloud.typesense.org/api/v1/clusters/<ClusterId>/backup-settings" \
      -H "Accept: application/json" \
      -H "X-TYPESENSE-CLOUD-MANAGEMENT-API-KEY: YOUR-API-KEY"

Response:

{
  "enabled": true,
  "frequency_hours": 12,
  "retention_days": 14,
  "regions": [
    "oregon",
    "frankfurt"
  ],
  "start_hour_utc": 3,
  "restore_test_enabled": true,
  "next_backup_at": 1792465200,
  "estimated_monthly_cost": {
    "total_cents": 4305,
    "storage_cents": 1355,
    "bandwidth_cents": 2927,
    "restore_test_cents": 23,
    "backups_kept": 28,
    "uploads_per_day": 2,
    "price_per_gb_month_cents": {
      "oregon": 10,
      "frankfurt": 10
    },
    "data_size_bytes": 2420000000,
    "data_size_source": "latest_backup"
  }
}

A cluster that has never had backups returns the defaults: backups off, taken every 24 hours, kept for 7 days in the cluster's own region, with the monthly restore test on. start_hour_utc defaults to an hour of the day picked for the cluster.

# Response Parameters

Field Description
enabled Whether backups are taken on schedule.
frequency_hours Hours between backups: 3, 6, 12 or 24.
retention_days Days each new backup is kept: 7, 14 or 30.
regions The regions each backup is stored in. Region names are the same as in cluster regions.
start_hour_utc The hour of the day's first backup, in UTC, from 0 to 23. Backups are taken at this hour and every frequency_hours after it.
restore_test_enabled Whether the latest backup is restored to a temporary cluster once a month to check that it restores. See Restore test.
next_backup_at Unix timestamp in seconds of the next scheduled backup. null while backups are off.
estimated_monthly_cost The estimated cost of these settings over a 30-day month, at the cluster's current data size. null when the data size is not known yet, or the cluster is terminated.

# estimated_monthly_cost

All amounts are in US cents.

Field Description
total_cents Storage plus bandwidth, plus the restore test when restore_test_enabled is true.
storage_cents The storage of the backups kept, in every region.
bandwidth_cents The bandwidth to upload each backup to every region.
restore_test_cents The cost of the monthly restore test. It's included even when the test is off, and only counted in total_cents when it's on.
backups_kept How many backups are kept at a time in each region.
uploads_per_day How many backups are taken each day.
price_per_gb_month_cents The storage price per GB-month in each region.
data_size_bytes The data size the estimate is based on.
data_size_source latest_backup when the estimate uses the size of the latest backup, or cluster_disk when it uses the data disk in use now, before the first backup.

# Change backup settings

This endpoint turns backups on or off, or changes their settings. It only changes the settings you send:

curl -X PUT --location "https://cloud.typesense.org/api/v1/clusters/<ClusterId>/backup-settings" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-TYPESENSE-CLOUD-MANAGEMENT-API-KEY: YOUR-API-KEY" \
    -d '{
          "enabled": true,
          "frequency_hours": 12,
          "retention_days": 14,
          "regions": ["oregon", "frankfurt"],
          "start_hour_utc": 3
        }'

Response:

Here are the settings as saved, in the same format as Get backup settings:

{
  "enabled": true,
  "frequency_hours": 12,
  "retention_days": 14,
  "regions": [
    "oregon",
    "frankfurt"
  ],
  "start_hour_utc": 3,
  "restore_test_enabled": true,
  "next_backup_at": 1792465200,
  "estimated_monthly_cost": {
    "total_cents": 4305,
    "storage_cents": 1355,
    "bandwidth_cents": 2927,
    "restore_test_cents": 23,
    "backups_kept": 28,
    "uploads_per_day": 2,
    "price_per_gb_month_cents": {
      "oregon": 10,
      "frankfurt": 10
    },
    "data_size_bytes": 2420000000,
    "data_size_source": "latest_backup"
  }
}

Note

You want to check estimated_monthly_cost from Get backup settings before you turn backups on. Each region you add stores its own copy of every backup and adds its own upload.

# Request Parameters

Parameter Required Description
enabled Optional true turns backups on. false turns them off. Backups already kept stay until they expire.
frequency_hours Optional Hours between backups: 3, 6, 12 or 24.
retention_days Optional Days each backup is kept: 7, 14 or 30. A new retention only applies to new backups. Backups already taken keep the expiry they were taken with.
regions Optional An array of 1 to 3 different regions to store each backup in, for example ["oregon", "frankfurt"]. A new list only applies to new backups.
start_hour_utc Optional The hour of the day's first backup, in UTC, from 0 to 23. With "start_hour_utc": 3 and "frequency_hours": 12, backups are taken at 03:00 and 15:00 UTC.
restore_test_enabled Optional true turns on the monthly restore test.

# Error Responses

The API returns HTTP 400 and leaves the settings unchanged when a parameter isn't valid. It returns HTTP 402 when backups would be on and the account has neither a payment method nor prepaid credits. It returns HTTP 409 when the cluster is terminated.

# List backups

This endpoint lists every backup the cluster keeps, newest first, with the regions each one is stored in and when it expires:

curl -X GET --location "https://cloud.typesense.org/api/v1/clusters/<ClusterId>/backups" \
      -H "Accept: application/json" \
      -H "X-TYPESENSE-CLOUD-MANAGEMENT-API-KEY: YOUR-API-KEY"

Response:

{
  "backup_in_progress": false,
  "backups": [
    {
      "id": 48213,
      "status": "succeeded",
      "kind": "scheduled",
      "size_bytes": 2420000000,
      "regions": [
        "oregon",
        "frankfurt"
      ],
      "taken_at": 1792422000,
      "completed_at": 1792422240,
      "expires_at": 1793631840,
      "deleted_at": null
    },
    {
      "id": 48177,
      "status": "succeeded",
      "kind": "scheduled",
      "size_bytes": 2418000000,
      "regions": [
        "oregon",
        "frankfurt"
      ],
      "taken_at": 1792378800,
      "completed_at": 1792379040,
      "expires_at": 1793588640,
      "deleted_at": null
    }
  ]
}

A backup is listed once it completes. While one is being taken, backup_in_progress is true. A backup is no longer listed once it expires.

# Response Parameters

Field Description
id The backup ID, used to delete or restore the backup.
status See status.
kind scheduled for a backup taken on the cluster's backup schedule. pre_termination for the snapshot kept when a cluster was terminated because the account used up its free tier or didn't pay its invoices (see Bringing back a terminated cluster).
size_bytes The size of the backup.
regions The regions the backup is stored in. Empty once the backup is deleted.
taken_at Unix timestamp in seconds when the backup started.
completed_at Unix timestamp in seconds when the backup completed.
expires_at Unix timestamp in seconds when the backup expires. An expired backup is deleted automatically.
deleted_at Unix timestamp in seconds when the backup was deleted, or null.

# status

status Description
succeeded The backup is kept, and can be restored or deleted.
deleting The backup is being deleted. It can't be restored any more.
deleted The backup was deleted. A backup you delete is listed with this status for one hour after deletion.

# Delete a backup

This endpoint deletes a backup from every region it's stored in.

curl -X DELETE --location "https://cloud.typesense.org/api/v1/clusters/<ClusterId>/backups/<BackupId>" \
      -H "Accept: application/json" \
      -H "X-TYPESENSE-CLOUD-MANAGEMENT-API-KEY: YOUR-API-KEY"

Response:

{
  "id": 48177,
  "status": "deleting",
  "size_bytes": 2418000000,
  "regions": [
    "oregon",
    "frankfurt"
  ],
  "taken_at": 1792378800,
  "completed_at": 1792379040,
  "expires_at": 1793588640,
  "deleted_at": null
}

Deletion runs in the background and takes up to a few minutes. Sending the same request again while the backup is being deleted returns the same response.

# Error Responses

The API returns HTTP 404 when the cluster has no backup with this ID, or the backup has already been deleted.

{
  "success": false,
  "message": "Resource Not Found"
}

# Restore a backup

This endpoint restores a backup, either to a new cluster or onto this cluster. The restore runs in the background, as a cloning operation, and takes from a few minutes to several hours depending on the data.

curl -X POST --location "https://cloud.typesense.org/api/v1/clusters/<ClusterId>/backups/<BackupId>/restore" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-TYPESENSE-CLOUD-MANAGEMENT-API-KEY: YOUR-API-KEY" \
    -d '{
          "target": "new_cluster",
          "region": "oregon",
          "name": "products-restored"
        }'

Response:

{
  "success": true,
  "cloning_operation": {
    "id": "3d0c6f8e-6a1b-4f0e-9a52-1c7b2e4d9f13",
    "status": "pending",
    "created_at": 1792436400,
    "updated_at": 1792436400,
    "completed_at": null,
    "source_region": "oregon",
    "target_region": "oregon",
    "typesense_server_version": "29.0",
    "target_cluster_name": "products-restored",
    "target_cluster_reference_id": null,
    "notification_email_addresses": []
  }
}

You want to poll the cloning operation info endpoint with the returned id about every 60 seconds until its status is succeeded. For a restore to a new cluster, target_cluster_reference_id then holds the new cluster's ID.

source_region is the region the backup is read from: the backup's copy in the target region when there is one, otherwise another region the backup is stored in.

IMPORTANT

A restore with "target": "in_place" replaces all of the cluster's data with the backup's data, and can't be undone. The cluster can't serve searches or writes while it restores.

# Request Parameters

Parameter Required Description
target Required new_cluster or in_place, as described below.
region Optional new_cluster only. The region of the new cluster. Default: this cluster's region. When the backup isn't stored in that region, it's copied there, and the copy is billed as bandwidth (see Billing).
name Optional new_cluster only. A name for the new cluster.
target Description
new_cluster Restores the backup to a new single-node cluster with this cluster's RAM, CPU and GPU configuration, on the Typesense version the backup was taken on.
in_place Restores the backup onto this cluster, replacing all of its data. Only for a single-node cluster that is In Service, with no other operation running or scheduled. The cluster keeps its Typesense version, so the backup must have been taken on the same or an older version.

# Error Responses

The API returns HTTP 400 and doesn't start the restore when:

  • a parameter isn't valid
  • for in_place: the cluster doesn't meet the conditions in the target table above
  • for new_cluster: the Typesense version the backup was taken on is no longer available for new clusters

It returns HTTP 402 when you restore to a new cluster and the account has neither a payment method nor a positive prepaid credit balance. It returns HTTP 403 when you restore to a new cluster and the account has unpaid invoices with failed payments. It returns HTTP 422 when the account has reached its maximum number of clusters, or the backup has expired. It returns HTTP 404 when the cluster has no backup with this ID that can be restored, for example one that's being deleted.

# Restore test

With restore_test_enabled on, we restore the latest backup to a temporary single-node cluster about once a month, and check that the restored cluster holds the backup's collections and documents. While the test runs, the temporary cluster appears in your cluster list, named [Automated] Backup Restore Testing on <date>. It's terminated automatically once the check finishes.

When the backup has no copy in the cluster's own region, copying it there is billed as bandwidth.

# When backups run

Backups are taken while the cluster is In Service, at start_hour_utc and every frequency_hours after it. A scheduled backup is skipped, and the next one is taken at its usual time, when:

  • the previous backup is still running
  • the account no longer has a payment method or prepaid credits
  • another operation on the cluster (a configuration change, a rolling restart or a cloning operation) is running or about to start

While a backup is running, the cluster can't be cloned and its configuration can't be changed. Those requests return HTTP 400 until it finishes.

# Backups and terminated clusters

When you terminate a cluster, no new backups are taken. Its kept backups stay until they expire, unless you send "delete_backups": true with the terminate request, in which case they're deleted along with the cluster.

Kept backups of a terminated cluster can still be listed, deleted and restored to a new cluster. Their storage through their expiry is billed when the cluster is terminated. List all clusters keeps returning a cluster terminated more than a week ago while it still has kept backups, but only to a key with the backups:read capability.

# Bringing back a terminated cluster

When a cluster is terminated because the account used up its free tier or didn't pay its invoices, we take a snapshot of its data first and keep it for 30 days at no charge. It's listed with "kind": "pre_termination".

Once the account has a payment method or enough prepaid credit for a new cluster, and it has no unpaid invoices, you can restore it to a new cluster with "target": "new_cluster". The new cluster gets the terminated cluster's ID and hostname back, so your app doesn't need a config change.

A terminated cluster can be brought back only once. The restore returns HTTP 400 when the cluster has already been brought back, or when a restore of it is still running. It returns HTTP 402 when the account has neither a payment method nor enough prepaid credit for a new cluster, or still has unpaid invoices.

# Billing

  • Storage: each backup is billed for the data it holds in each region it's stored in, per GB-month, at that region's price (price_per_gb_month_cents). Storage is measured daily and billed on the next invoice, as a backup_storage invoice line item for each cluster and region.
  • Bandwidth: each backup is uploaded once to each region. The upload to the first region is counted in the cluster's regular bandwidth usage. Each copy to a further region is billed as bandwidth in whole GB, at least 1 GB per copy. Restoring a backup from a region other than the target region is billed the same way.
  • Restore test: billed as node hours of the temporary cluster.

# Permissions

To get backup settings or list backups, you need a key with the backups:read capability. To change backup settings or delete a backup, you need backups:manage. To restore a backup, you need backups:restore. See capabilities.

This documentation site is open source. Found an issue? Edit this page (opens new window) and send us a Pull Request.

For AI Agents: View an easy-to-parse, token-efficient Markdown version of this page. You can also replace .html with .md in any docs URL. For paths ending in /, append README.md to the path.

Last Updated: 10/27/2026, 9:31:52 PM