Skip to content
Coritan Docs

Keep earlier versions of objects

Turn on versioning to keep what an overwrite or a delete replaces, then list, restore or delete versions and remove delete markers.

View as Markdown

Versioning keeps the copy of an object that an overwrite or a delete replaces, so you can bring back a file that was overwritten or deleted by mistake. Each copy is a version. Every version you keep counts toward the storage you pay for.

You turn versioning on when you create a bucket, or later in the bucket's Settings tab. Once it is on, you cannot turn it off. You can only suspend it.

  • Sign in to the dashboard and open the service. The service must be active to change versioning and to restore or delete versions. You can list versions and read their details in any status.
  • Older versions are billed as stored data until you delete them (Versions and your bill). A lifecycle rule can delete them for you after a number of days (Rules on a bucket that keeps versions).

A bucket's versioning is Off, On or Suspended:

Off
The default. An upload replaces an object that has the same key, and a delete destroys the object. Nothing is kept.
On
An upload to a key that exists makes a new current version, and the one it replaces stays as an older version. A delete adds a delete marker: the object leaves the listing, and every version stays under the marker. Remove the marker and the object is back.
Suspended
The bucket keeps the versions it holds, and you can still restore or delete them. New uploads and deletes keep no copy of what they replace.

Each version has a version ID. An object written while versioning was off has the ID null.

On a bucket that keeps versions, Delete object… and the other deletes in the object list add a delete marker instead of destroying the object. The dialog says so. To destroy data for good, delete the versions themselves (Delete a version for good).

To turn it on as you create a bucket:

  1. Open the service, select the Buckets tab, then select Create bucket….
  2. Fill in Name and choose the Region (Create a bucket).
  3. Tick Keep versions.
  4. Select Create bucket.

Object Lock turns versioning on as well, so ticking it ticks Keep versions and greys it out (Protect objects with Object Lock).

To turn it on for a bucket you have:

  1. Open the service, select the Buckets tab, then select the bucket. You can also select Settings in the bucket's menu.
  2. Select the Settings tab. The Versioning and Object Lock card shows Versioning as Off.
  3. Select Turn on versioning…, then Turn on versioning to confirm.

A message confirms it, such as Versioning is on for u7-assets. The bucket's header shows Versioning on.

  1. On the bucket's Settings tab, select Suspend versioning….
  2. Select Suspend versioning to confirm.

A message confirms it, such as Versioning is suspended for u7-assets. The header shows Versioning suspended. To start keeping versions again, select Turn versioning back on…, then Turn versioning back on.

A bucket with Object Lock keeps versioning on, so it has no Suspend versioning… button.

  1. Open the bucket and select the Objects tab.
  2. Turn on Show versions at the top of the Objects card. The card is now called Versions.

The list shows every version and delete marker in the folder, newest first under each key:

Name
The object's name on its newest row, then Older version on each row below it. Current marks the current version, and Delete marker marks a delete marker.
Version ID
The start of the version ID. Hover over it to see all of it.
Size and Modified
The version's size, and when it was written. A delete marker has no size.

The list shows 200 versions at a time. Select Load more for the next 200. Show versions stays on as you open folders, and it is part of the page address, so the back button and bookmarks keep it. While it is on, Upload… and New folder… are hidden. Turn it off to upload.

Show versions appears only on a bucket whose versioning is on or suspended.

Select an object's name, or Details in its menu. A panel opens for that version:

  • Object: the key, size, type, when it was modified, its ETag, and its Version ID with a button to copy it.
  • Metadata and Tags, when it has any.
  • Object Lock, on a bucket with Object Lock (Protect objects with Object Lock).
  • Versions: the key's versions and delete markers, newest first, up to 50. Showing marks the version the panel shows. Select another date to open that version.

An older version shows This is an older version at the top.

  1. Turn on Show versions, open the older version's menu and select Restore this version…. In the details panel, the same button is at the bottom.
  2. Select Restore version to confirm.

We copy the version over the current one, with its metadata and tags. The copy becomes the current version, and the version it replaced stays in the list. A message confirms it, such as team.jpg restored. The copy is the current version now.

The dashboard restores versions of up to 5 GB. For a larger version, download it with an S3 client and upload it again, which makes it the current version:

Shell
aws --profile coritan s3api get-object --bucket u7-assets --key videos/launch.mp4 \
  --version-id 3sL4kqtJlcpXroDTDmJ.rmSpXd3dIbrHY launch.mp4
aws --profile coritan s3 cp launch.mp4 s3://u7-assets/videos/launch.mp4

While versioning is on, a delete adds a delete marker and keeps the object's versions. To bring the object back:

  1. Turn on Show versions and open the object's folder.
  2. Open the menu of the row marked Delete marker and select Remove delete marker….
  3. Select Remove delete marker to confirm.

The version under the marker becomes the current version again. A message confirms it, such as Delete marker removed. old-banner.jpg is back.

Caution

Deleting a version destroys it. There is no undo.

  1. Turn on Show versions, open the version's menu and select Delete version…. In the details panel, the same button is at the bottom.
  2. Type the object's name, which is the part of its key after the last /, such as team.jpg.
  3. Select Delete version.

A message confirms it, such as That version of team.jpg is deleted. When you delete the current version, the next newest version becomes current.

On a bucket with Object Lock, a version under retention or a legal hold cannot be deleted this way (Delete a locked version).

Turn on Show versions, open the older version's menu and select Download. In the details panel, Download downloads the version the panel shows.

Through the API, ask POST /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/objects/presign with {"key": "photos/team.jpg", "op": "get", "version_id": "<version ID>"}. The answer's url downloads that version, and its version_id names it.

To download an older version with an S3 client, copy its ID from the details panel and pass it with --version-id:

Shell
aws --profile coritan s3api get-object --bucket u7-assets --key photos/team.jpg \
  --version-id 3sL4kqtJlcpXroDTDmJ.rmSpXd3dIbrHY team.jpg
  • Every version you keep is stored data and is billed as an object of its size would be (How Object Storage is billed). A 10 MB file that you overwrite 9 times stores 100 MB.
  • Delete markers hold no data.
  • On the Buckets tab, Size counts every version and Objects counts only current objects. Both come from the hourly measurement.
  • To stop older versions adding up, delete the ones you no longer need, or add a lifecycle rule with Delete old versions (Lifecycle rules).

Use versions with an S3 client

Section titled Use versions with an S3 client

An access key with Read and write permissions, whose scope covers the bucket, can:

  • list versions with aws s3api list-object-versions;
  • read a version with get-object and --version-id;
  • delete a version with delete-object and --version-id, unless Object Lock protects it.

put-bucket-versioning answers 403 AccessDenied with every access key. Turn versioning on or suspend it in the Settings tab or through the API (S3 compatibility).

Shell
aws --profile coritan s3api list-object-versions --bucket u7-assets --prefix photos/team.jpg

A delete-object without --version-id adds a delete marker, as a delete in the dashboard does.

Delete a bucket that keeps versions

Section titled Delete a bucket that keeps versions

Deleting a bucket destroys every version and delete marker in it. A bucket with no current objects can still hold older versions and delete markers, so its delete dialog offers Destroy any older versions and delete markers in it. Tick it, or we refuse the delete while any remain (Delete a bucket).

While versioning is on, the bucket's header shows Versioning on, the Objects tab has Show versions, and every overwrite and delete keeps what it replaced. The bucket's size on the Buckets tab includes its older versions from the next hourly measurement.

Show versions is missing
The bucket's versioning is off. Turn it on in the bucket's Settings tab.
Turn on versioning… and Suspend versioning… are missing
The service is not active, or the bucket has Object Lock, which keeps versioning on.
This version is not there with It may have been deleted, or it is a delete marker.
The version was deleted after the list loaded, or the row is a delete marker, which holds no object. Select the refresh button on the Objects card.
This version is larger than 5 GB, which is the most we copy in one request. Copy it with an S3 client instead.
Download the version with an S3 client and upload it again (Restore an older version).
u7-assets does not keep versions, so there is nothing to restore.
The bucket's versioning is off. Only a bucket whose versioning is on or suspended has versions to restore.
The bucket's size went up after you turned versioning on
Each overwrite and delete now keeps a version, and versions are stored data. Delete versions you do not need, or add a lifecycle rule (Versions and your bill).
u7-assets still holds object versions. Delete it with force to destroy every version as well.
The bucket has older versions or delete markers. Tick the box in the delete dialog, or send force=true through the API.
Too many requests for this action. Try again later.
Your account made 300 versioning, retention and version changes in the last hour. Wait, then try again.
This service is suspended; it can be changed once it is active
Pay the overdue invoice (Failed payments and suspended services), then try again. You can still list versions and read their details.

Each request takes the service ID and the bucket ID, from GET /api/v1/client/object-storage/{service_id}/buckets. A service that is not Object Storage on your account answers 404 with Object storage service not found, and a bucket that is not on the service answers 404 with Bucket not found.

Each bucket in the list carries versioning, which is off, enabled or suspended, and object_lock (Protect objects with Object Lock). To create a bucket that keeps versions, add "versioning": true to POST /api/v1/client/object-storage/{service_id}/buckets:

Shell
curl -X POST https://api.coritan.com/api/v1/client/object-storage/1207/buckets \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "assets", "versioning": true}'

Turn versioning on or suspend it

Section titled Turn versioning on or suspend it

PUT /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/versioning takes status, which is enabled or suspended:

Shell
curl -X PUT https://api.coritan.com/api/v1/client/object-storage/1207/buckets/31/versioning \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "enabled"}'
JSON
{
  "bucket_id": 31,
  "versioning": "enabled",
  "object_lock": {"enabled": false, "mode": null, "days": null, "years": null}
}

There is no off: any other status answers 422.

GET /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/objects/versions lists one page of versions and delete markers, by key and newest first. It takes these query parameters:

prefix
Only keys that start with it, up to 1024 characters. Give a folder with its /, such as photos/.
max_keys
How many versions and delete markers a page holds, from 1 to 1000. The default is 100.
key_marker and version_marker
The next_key_marker and next_version_marker of the previous page, to read the next one.
flat
true lists every key under the prefix, with no folders. The default, false, lists the folders under the prefix in prefixes.
Shell
curl "https://api.coritan.com/api/v1/client/object-storage/1207/buckets/31/objects/versions?prefix=photos/" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "items": [
    {"key": "photos/old-banner.jpg", "version_id": "Kq2vO0n4yPnBh7x1VxN3w5Wq9cAZr6sT", "is_latest": true, "is_delete_marker": true, "size": null, "last_modified": "2026-09-21T08:15:40+00:00", "etag": null},
    {"key": "photos/old-banner.jpg", "version_id": "null", "is_latest": false, "is_delete_marker": false, "size": 90211, "last_modified": "2026-08-30T10:02:00+00:00", "etag": "1f3870be274f6c49b3e31a0c6728957f"},
    {"key": "photos/team.jpg", "version_id": "3sL4kqtJlcpXroDTDmJ.rmSpXd3dIbrHY", "is_latest": true, "is_delete_marker": false, "size": 482113, "last_modified": "2026-09-20T14:02:11+00:00", "etag": "9b2cf535f27731c974343645a3985328"}
  ],
  "prefixes": ["photos/2026/"],
  "prefix": "photos/",
  "next_key_marker": null,
  "next_version_marker": null
}

is_latest marks each key's current version or delete marker. size is in bytes, and null for a delete marker. The markers are null on the last page. On a bucket that never kept versions, each object is listed once with version_id null.

GET /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/objects/details takes key and, for a version other than the current one, version_id:

Shell
curl "https://api.coritan.com/api/v1/client/object-storage/1207/buckets/31/objects/details?key=photos/team.jpg" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "key": "photos/team.jpg",
  "version_id": "3sL4kqtJlcpXroDTDmJ.rmSpXd3dIbrHY",
  "is_latest": true,
  "size": 482113,
  "content_type": "image/jpeg",
  "etag": "9b2cf535f27731c974343645a3985328",
  "last_modified": "2026-09-20T14:02:11+00:00",
  "metadata": {"author": "studio"},
  "tags": [{"key": "team", "value": "marketing"}],
  "retention": null,
  "legal_hold": false,
  "object_lock": false,
  "versioning": "enabled",
  "versions": [
    {"key": "photos/team.jpg", "version_id": "3sL4kqtJlcpXroDTDmJ.rmSpXd3dIbrHY", "is_latest": true, "is_delete_marker": false, "size": 482113, "last_modified": "2026-09-20T14:02:11+00:00", "etag": "9b2cf535f27731c974343645a3985328"},
    {"key": "photos/team.jpg", "version_id": "hX0p8Y2kW1cS7fRbN4eD6gA9vLmQ3tZu", "is_latest": false, "is_delete_marker": false, "size": 455020, "last_modified": "2026-09-02T09:40:27+00:00", "etag": "c4ca4238a0b923820dcc509a6f75849b"}
  ],
  "versions_truncated": false
}

metadata holds the object's x-amz-meta-* values. versions lists the key's versions and delete markers, newest first, up to 50, and versions_truncated is true when there are more. retention and legal_hold are described in Protect objects with Object Lock. A key or version that does not exist, or a version that is a delete marker, answers 404.

POST /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/objects/restore copies a version over the current one, with its metadata and tags:

Shell
curl -X POST https://api.coritan.com/api/v1/client/object-storage/1207/buckets/31/objects/restore \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"key": "photos/team.jpg", "version_id": "hX0p8Y2kW1cS7fRbN4eD6gA9vLmQ3tZu"}'
JSON
{"ok": true, "key": "photos/team.jpg", "restored_from": "hX0p8Y2kW1cS7fRbN4eD6gA9vLmQ3tZu", "version_id": "Vb7nR2qP5tL0wE3yU8iO1aS4dF6gH9jK"}

version_id is the ID of the new current version.

Delete a version or a delete marker

Section titled Delete a version or a delete marker

DELETE /api/v1/client/object-storage/{service_id}/buckets/{bucket_id}/objects/version deletes one version or delete marker for good. The body takes key and version_id:

Shell
curl -X DELETE https://api.coritan.com/api/v1/client/object-storage/1207/buckets/31/objects/version \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"key": "photos/old-banner.jpg", "version_id": "Kq2vO0n4yPnBh7x1VxN3w5Wq9cAZr6sT"}'
JSON
{"ok": true, "key": "photos/old-banner.jpg", "version_id": "Kq2vO0n4yPnBh7x1VxN3w5Wq9cAZr6sT", "delete_marker": true}

delete_marker is true when what you removed was a delete marker, which brings back the version under it. On a bucket with Object Lock, a locked version takes bypass_governance and confirm as well (Delete a locked version).

Where detail is an object, error is a code your program can test and message is a sentence you can show.

Status detail Cause
404 An object with "error": "version_not_found" The key or version does not exist, or the version is a delete marker.
409 An object with "error": "versioning_refused" You asked to suspend versioning on a bucket with Object Lock, or to restore on a bucket that does not keep versions.
409 An object with "error": "version_locked" Object Lock protects the version (Delete a locked version).
409 This service is pending; it can be changed once it is active The service is not active. The message names its status.
422 An object with "error": "too_large_to_restore" The version is larger than 5 GB.
422 A list of fields The body or a query parameter is not in the shape above.
429 An object with "error": "rate_limited" and retry_after_seconds Your account made 300 versioning, retention and version changes in the last hour. The Retry-After header says how long to wait.
502 A message that starts Could not, such as Could not restore photos/team.jpg: and a reason The bucket's region refused the request. Try again in a minute.

API operations on this page