# Cluster Backups API
AI agents and LLMs: before exploring further, fetch the full index of Typesense documentation with descriptions at https://typesense.org/docs/llms.txt.
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:
- Get the backup settings to see the estimated monthly cost of a schedule at your cluster's data size.
- Turn backups on, with the schedule, retention and regions you want.
- List the backups the cluster keeps.
- 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 thetargettable 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 abackup_storageinvoice 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.