# Organization API: Customer Portal: Buckets

> The 23 Organization API operations for buckets.

Source: https://www.coritan.com/docs/api/reference/organizations/customer-portal/object-storage-buckets/

Part of [Customer Portal](/docs/api/reference/organizations/customer-portal/).

## Operations

| Method | Path | Summary |
| --- | --- | --- |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets) | List buckets |
| POST | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets`](#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets) | Make a bucket in the chosen region, or the service's home region |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id) | One bucket with its size, object count, rule counts, versioning and Object Lock |
| DELETE | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}`](#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id) | Delete a bucket |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-cors) | Get bucket cors |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-cors) | Replace the bucket's CORS rules with the ones sent, at most 99 |
| DELETE | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`](#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-c) | Remove every CORS rule from the bucket |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life) | The bucket's lifecycle rules: what we delete from it, and when |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life) | Replace the bucket's lifecycle rules with the ones sent, at most 100 |
| DELETE | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`](#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-l) | Remove every lifecycle rule from the bucket, the default one included |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle/runs`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life) | List lifecycle runs |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/object-lock`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | Whether the bucket has Object Lock, and the default retention it gives every new version |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/object-lock`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | Change the default retention of a bucket that has Object Lock |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | One page of the bucket under prefix, folders first |
| DELETE | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects`](#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-o) | Delete up to 1000 named objects |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/details`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | Get object details |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/legal-hold`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | Put a legal hold on a version, or take it off |
| POST | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/presign`](#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obj) | A short-lived URL a browser or app uses directly for one GET, PUT or DELETE of one object |
| POST | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/restore`](#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obj) | Restore object version |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/retention`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | Give a version a retention, or change the one it has |
| DELETE | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/version`](#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-o) | Delete one version or delete marker for good |
| GET | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/versions`](#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje) | List object versions |
| PUT | [`/api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/versioning`](#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-vers) | Turn versioning on for a bucket, or suspend it |

### List buckets {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets`

The service's buckets, by name, with their size, object count, rule counts, versioning and Object Lock.

``bucket_prefix`` is what every name starts with, and ``max_buckets`` the
most buckets the service can hold. ``public_url`` is always null and
``custom_domains`` always 0, because public access is not offered to a
brand's customers.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `items` | array of BucketOut |  |
| `items[].id` | integer |  |
| `items[].name` | string |  |
| `items[].region` | string or null |  |
| `items[].location_id` | integer or null |  |
| `items[].location_name` | string or null |  |
| `items[].quota_bytes` | integer or null |  |
| `items[].used_bytes` | integer |  |
| `items[].object_count` | integer |  |
| `items[].usage_measured_at` | string or null |  |
| `items[].created_at` | string or null |  |
| `items[].deleted_at` | string or null |  |
| `items[].endpoint` | string or null |  |
| `items[].url` | string or null |  |
| `items[].cors_rules` | integer | How many CORS rules the bucket has |
| `items[].lifecycle_rules` | integer | How many lifecycle rules the bucket has |
| `items[].public_url` | string or null | The bucket's public URL while it is on, otherwise null |
| `items[].custom_domains` | integer | How many custom domains are linked to the bucket |
| `items[].versioning` | string, one of `off`, `enabled`, `suspended` | Whether the bucket keeps every version of its objects; once on, it is never off again |
| `items[].object_lock` | ObjectLockOut | A bucket's Object Lock and the default retention it gives new versions. |
| `items[].encryption` | boolean | True when objects written to the bucket are encrypted |
| `total` | integer |  |
| `bucket_prefix` | string |  |
| `max_buckets` | integer |  |

### Make a bucket in the chosen region, or the service's home region {#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets}

`POST /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets`

Make a bucket in the chosen region, or the service's home region.

``name`` is what the customer types. We add the customer's prefix, such as
``c42-``, when it is missing, so the bucket's full name is in the answer.
Names are 3 to 63 characters with the prefix, in lowercase letters, digits,
hyphens and dots. ``versioning`` keeps every version of every object from
the start. ``object_lock`` creates the bucket with Object Lock, which cannot
be added later and keeps versioning on for good; give it a ``mode`` and
``days`` or ``years`` for a default retention on every new version.

Answers 409 when the name is taken or the service already holds the most
buckets it can, 422 for a name or a default retention that is refused, and
409 when the service is not active.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `location_id` | integer or null | no |  |
| `versioning` | boolean | no | Keep every version of every object. Object Lock turns this on whatever it says |
| `object_lock` | ObjectLockCreate or null | no | Create the bucket with Object Lock, which cannot be added later. Leave out for no lock |
| `object_lock.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | no | The default retention's mode; leave out for a lock with no default retention |
| `object_lock.days` | integer or null | no | Default retention in days, from 1 to 36500 |
| `object_lock.years` | integer or null | no | Default retention in years, from 1 to 100, instead of days |
| `encryption` | boolean or null | no | Encrypt every object written to the bucket. Leave out to encrypt when default encryption is available. True while it is not available answers 409 |

#### Responses

| Status | Meaning |
| --- | --- |
| `201` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `201` response:

| Field | Type | Description |
| --- | --- | --- |
| `id` | integer |  |
| `name` | string |  |
| `region` | string or null |  |
| `location_id` | integer or null |  |
| `location_name` | string or null |  |
| `quota_bytes` | integer or null |  |
| `used_bytes` | integer |  |
| `object_count` | integer |  |
| `usage_measured_at` | string or null |  |
| `created_at` | string or null |  |
| `deleted_at` | string or null |  |
| `endpoint` | string or null |  |
| `url` | string or null |  |
| `cors_rules` | integer | How many CORS rules the bucket has |
| `lifecycle_rules` | integer | How many lifecycle rules the bucket has |
| `public_url` | string or null | The bucket's public URL while it is on, otherwise null |
| `custom_domains` | integer | How many custom domains are linked to the bucket |
| `versioning` | string, one of `off`, `enabled`, `suspended` | Whether the bucket keeps every version of its objects; once on, it is never off again |
| `object_lock` | ObjectLockOut | A bucket's Object Lock and the default retention it gives new versions. |
| `object_lock.enabled` | boolean | Whether the bucket was created with Object Lock |
| `object_lock.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | The default retention's mode; null for no default retention |
| `object_lock.days` | integer or null | How long the default retention keeps each new version, in days |
| `object_lock.years` | integer or null | ``days`` in years, when it is a whole number of years |
| `encryption` | boolean | True when objects written to the bucket are encrypted |

### One bucket with its size, object count, rule counts, versioning and Object Lock {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}`

One bucket with its size, object count, rule counts, versioning and Object Lock.

Answers 404 for a bucket that is not in this customer's service.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `id` | integer |  |
| `name` | string |  |
| `region` | string or null |  |
| `location_id` | integer or null |  |
| `location_name` | string or null |  |
| `quota_bytes` | integer or null |  |
| `used_bytes` | integer |  |
| `object_count` | integer |  |
| `usage_measured_at` | string or null |  |
| `created_at` | string or null |  |
| `deleted_at` | string or null |  |
| `endpoint` | string or null |  |
| `url` | string or null |  |
| `cors_rules` | integer | How many CORS rules the bucket has |
| `lifecycle_rules` | integer | How many lifecycle rules the bucket has |
| `public_url` | string or null | The bucket's public URL while it is on, otherwise null |
| `custom_domains` | integer | How many custom domains are linked to the bucket |
| `versioning` | string, one of `off`, `enabled`, `suspended` | Whether the bucket keeps every version of its objects; once on, it is never off again |
| `object_lock` | ObjectLockOut | A bucket's Object Lock and the default retention it gives new versions. |
| `object_lock.enabled` | boolean | Whether the bucket was created with Object Lock |
| `object_lock.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | The default retention's mode; null for no default retention |
| `object_lock.days` | integer or null | How long the default retention keeps each new version, in days |
| `object_lock.years` | integer or null | ``days`` in years, when it is a whole number of years |
| `encryption` | boolean | True when objects written to the bucket are encrypted |

### Delete a bucket {#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id}

`DELETE /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}`

Delete a bucket. It is refused with 409 while the bucket holds objects, unless ``force`` is true.

With ``force``, every object and every version in the bucket is deleted for
good. A bucket with Object Lock refuses while a version is still locked.
The bucket's name stays reserved for a short while after the delete.
Answers 409 when the service is not active.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |
| `force` | query | boolean | no | Delete the objects in the bucket as well Default: `False`. |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type |
| --- | --- |
| `ok` | boolean |
| `bucket` | string |
| `region` | string or null |
| `objects_destroyed` | integer |

### Get bucket cors {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-cors}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`

The bucket's CORS rules: which web pages on other sites may use it from a browser, with which methods and headers.

An empty list means the bucket has no rules of its own, and browsers on any
site can send it signed or presigned requests. An S3 client that reads the
bucket's CORS sees one more rule first, ``coritan-dashboard``, which lets
the storefront's file browser upload. This list never holds it.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of CorsRule |  |
| `rules[].id` | string or null | A name for the rule, up to 255 characters. Optional. |
| `rules[].allowed_origins` | array of string | Origins whose pages may use the bucket, such as https://example.com. Each may hold one *, as in https://*.example.com; * alone allows every origin. |
| `rules[].allowed_methods` | array of string | Any of GET, PUT, POST, DELETE and HEAD |
| `rules[].allowed_headers` | array of string | Request headers the page may send, such as Content-Type. Each may hold one *. |
| `rules[].expose_headers` | array of string | Response headers the page may read, such as ETag. No *. |
| `rules[].max_age_seconds` | integer or null | How long a browser may keep the answer to its preflight request, in seconds |
| `max_rules` | integer |  |

### Replace the bucket's CORS rules with the ones sent, at most 99 {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-cors}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`

Replace the bucket's CORS rules with the ones sent, at most 99.

The rules follow Amazon S3's: each needs at least one origin and one method
(GET, PUT, POST, DELETE or HEAD); an origin or an allowed header may hold
one ``*``; exposed headers hold none. A browser request uses the first rule
that matches its origin, method and headers. The storefront's own origin
stays allowed beside the rules sent. Answers 422 with the rule at fault, 409
when the service is not active, and 429 after 60 rule changes in an hour. An
empty list removes every rule, as DELETE does. The rules apply within a
minute.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `rules` | array of CorsRule | yes | Every rule the bucket should have, at most 99: S3 holds 100 and the dashboard keeps one so its file browser can upload. An empty list removes them all. |
| `rules[].id` | string or null | no | A name for the rule, up to 255 characters. Optional. |
| `rules[].allowed_origins` | array of string | yes | Origins whose pages may use the bucket, such as https://example.com. Each may hold one *, as in https://*.example.com; * alone allows every origin. |
| `rules[].allowed_methods` | array of string | yes | Any of GET, PUT, POST, DELETE and HEAD |
| `rules[].allowed_headers` | array of string | no | Request headers the page may send, such as Content-Type. Each may hold one *. |
| `rules[].expose_headers` | array of string | no | Response headers the page may read, such as ETag. No *. |
| `rules[].max_age_seconds` | integer or null | no | How long a browser may keep the answer to its preflight request, in seconds |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of CorsRule |  |
| `rules[].id` | string or null | A name for the rule, up to 255 characters. Optional. |
| `rules[].allowed_origins` | array of string | Origins whose pages may use the bucket, such as https://example.com. Each may hold one *, as in https://*.example.com; * alone allows every origin. |
| `rules[].allowed_methods` | array of string | Any of GET, PUT, POST, DELETE and HEAD |
| `rules[].allowed_headers` | array of string | Request headers the page may send, such as Content-Type. Each may hold one *. |
| `rules[].expose_headers` | array of string | Response headers the page may read, such as ETag. No *. |
| `rules[].max_age_seconds` | integer or null | How long a browser may keep the answer to its preflight request, in seconds |
| `max_rules` | integer |  |

### Remove every CORS rule from the bucket {#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-c}

`DELETE /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/cors`

Remove every CORS rule from the bucket. Browsers on any site can then send it signed or presigned requests.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of CorsRule |  |
| `rules[].id` | string or null | A name for the rule, up to 255 characters. Optional. |
| `rules[].allowed_origins` | array of string | Origins whose pages may use the bucket, such as https://example.com. Each may hold one *, as in https://*.example.com; * alone allows every origin. |
| `rules[].allowed_methods` | array of string | Any of GET, PUT, POST, DELETE and HEAD |
| `rules[].allowed_headers` | array of string | Request headers the page may send, such as Content-Type. Each may hold one *. |
| `rules[].expose_headers` | array of string | Response headers the page may read, such as ETag. No *. |
| `rules[].max_age_seconds` | integer or null | How long a browser may keep the answer to its preflight request, in seconds |
| `max_rules` | integer |  |

### The bucket's lifecycle rules: what we delete from it, and when {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`

The bucket's lifecycle rules: what we delete from it, and when.

New buckets start with one rule (``default_rule_id``) that aborts
unfinished multipart uploads after 7 days. Rules run once a day, so an
object can stay up to a day after its rule makes it due.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of LifecycleRule |  |
| `rules[].id` | string or null | A name for the rule, unique in the bucket. Blank names become rule-1, rule-2 and so on. |
| `rules[].enabled` | boolean | False keeps the rule without applying it |
| `rules[].prefix` | string | Only keys that start with this. Empty means every key. |
| `rules[].tags` | array of LifecycleTag | Only objects with all of these tags, up to 10 |
| `rules[].object_size_greater_than` | integer or null | Only objects larger than this many bytes |
| `rules[].object_size_less_than` | integer or null | Only objects smaller than this many bytes |
| `rules[].expiration_days` | integer or null | Delete objects this many days after they were uploaded |
| `rules[].expiration_date` | string or null | Delete objects from this date on, YYYY-MM-DD, at midnight UTC |
| `rules[].expired_object_delete_marker` | boolean | Remove a delete marker once it is the only version of its key left |
| `rules[].noncurrent_days` | integer or null | Delete an old version this many days after a newer one replaced it |
| `rules[].newer_noncurrent_versions` | integer or null | Keep this many of the newest old versions whatever their age, 1–100. Needs noncurrent_days. |
| `rules[].abort_incomplete_multipart_days` | integer or null | Abort a multipart upload this many days after it started, if it is still unfinished |
| `max_rules` | integer |  |
| `default_rule_id` | string | The ID of the rule new buckets start with |

### Replace the bucket's lifecycle rules with the ones sent, at most 100 {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`

Replace the bucket's lifecycle rules with the ones sent, at most 100.

Each rule picks objects by key prefix, tags and size, and needs at least one
action: delete objects some days after upload or from a date, delete old
versions some days after they were replaced (keeping the newest few if
asked), remove delete markers that are the only version left, or abort
multipart uploads still unfinished after some days. Days count from the
object's upload time, in UTC. Transitions to another storage class are
refused. Answers 422 with the rule at fault, 409 when the service is not
active, and 429 after 60 rule changes in an hour. An empty list removes
every rule, as DELETE does. Deletions the rules make are free.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `rules` | array of LifecycleRuleIn | yes | Every rule the bucket should have, at most 100. An empty list removes them all. |
| `rules[].id` | string or null | no | A name for the rule, unique in the bucket. Blank names become rule-1, rule-2 and so on. |
| `rules[].enabled` | boolean | no | False keeps the rule without applying it |
| `rules[].prefix` | string | no | Only keys that start with this. Empty means every key. |
| `rules[].tags` | array of LifecycleTag | no | Only objects with all of these tags, up to 10 |
| `rules[].object_size_greater_than` | integer or null | no | Only objects larger than this many bytes |
| `rules[].object_size_less_than` | integer or null | no | Only objects smaller than this many bytes |
| `rules[].expiration_days` | integer or null | no | Delete objects this many days after they were uploaded |
| `rules[].expiration_date` | string or null | no | Delete objects from this date on, YYYY-MM-DD, at midnight UTC |
| `rules[].expired_object_delete_marker` | boolean | no | Remove a delete marker once it is the only version of its key left |
| `rules[].noncurrent_days` | integer or null | no | Delete an old version this many days after a newer one replaced it |
| `rules[].newer_noncurrent_versions` | integer or null | no | Keep this many of the newest old versions whatever their age, 1–100. Needs noncurrent_days. |
| `rules[].abort_incomplete_multipart_days` | integer or null | no | Abort a multipart upload this many days after it started, if it is still unfinished |
| `rules[].transitions` | array of any or null | no | Not offered. Any value is refused, since there is one storage class. |
| `rules[].noncurrent_version_transitions` | array of any or null | no | Not offered, as transitions |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of LifecycleRule |  |
| `rules[].id` | string or null | A name for the rule, unique in the bucket. Blank names become rule-1, rule-2 and so on. |
| `rules[].enabled` | boolean | False keeps the rule without applying it |
| `rules[].prefix` | string | Only keys that start with this. Empty means every key. |
| `rules[].tags` | array of LifecycleTag | Only objects with all of these tags, up to 10 |
| `rules[].object_size_greater_than` | integer or null | Only objects larger than this many bytes |
| `rules[].object_size_less_than` | integer or null | Only objects smaller than this many bytes |
| `rules[].expiration_days` | integer or null | Delete objects this many days after they were uploaded |
| `rules[].expiration_date` | string or null | Delete objects from this date on, YYYY-MM-DD, at midnight UTC |
| `rules[].expired_object_delete_marker` | boolean | Remove a delete marker once it is the only version of its key left |
| `rules[].noncurrent_days` | integer or null | Delete an old version this many days after a newer one replaced it |
| `rules[].newer_noncurrent_versions` | integer or null | Keep this many of the newest old versions whatever their age, 1–100. Needs noncurrent_days. |
| `rules[].abort_incomplete_multipart_days` | integer or null | Abort a multipart upload this many days after it started, if it is still unfinished |
| `max_rules` | integer |  |
| `default_rule_id` | string | The ID of the rule new buckets start with |

### Remove every lifecycle rule from the bucket, the default one included {#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-l}

`DELETE /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle`

Remove every lifecycle rule from the bucket, the default one included. Nothing is deleted from it on a schedule after this.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `rules` | array of LifecycleRule |  |
| `rules[].id` | string or null | A name for the rule, unique in the bucket. Blank names become rule-1, rule-2 and so on. |
| `rules[].enabled` | boolean | False keeps the rule without applying it |
| `rules[].prefix` | string | Only keys that start with this. Empty means every key. |
| `rules[].tags` | array of LifecycleTag | Only objects with all of these tags, up to 10 |
| `rules[].object_size_greater_than` | integer or null | Only objects larger than this many bytes |
| `rules[].object_size_less_than` | integer or null | Only objects smaller than this many bytes |
| `rules[].expiration_days` | integer or null | Delete objects this many days after they were uploaded |
| `rules[].expiration_date` | string or null | Delete objects from this date on, YYYY-MM-DD, at midnight UTC |
| `rules[].expired_object_delete_marker` | boolean | Remove a delete marker once it is the only version of its key left |
| `rules[].noncurrent_days` | integer or null | Delete an old version this many days after a newer one replaced it |
| `rules[].newer_noncurrent_versions` | integer or null | Keep this many of the newest old versions whatever their age, 1–100. Needs noncurrent_days. |
| `rules[].abort_incomplete_multipart_days` | integer or null | Abort a multipart upload this many days after it started, if it is still unfinished |
| `max_rules` | integer |  |
| `default_rule_id` | string | The ID of the rule new buckets start with |

### List lifecycle runs {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-life}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/lifecycle/runs`

The latest daily runs of the bucket's lifecycle rules, newest first: when each ran, what it removed and aborted, and what went wrong.

A run that stops before the end of a large bucket says so with ``complete``
false, and the next run carries on where it stopped. What a run could not
delete is still due, and the next run tries again.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |
| `limit` | query | integer | no | How many runs to return, newest first, 1–100 Default: `20`. |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `items` | array of LifecycleRun |  |
| `items[].id` | integer |  |
| `items[].started_at` | string or null |  |
| `items[].finished_at` | string or null | Empty while the run is going |
| `items[].removed_objects` | integer | Objects, old versions and delete markers removed |
| `items[].removed_bytes` | integer | Bytes deleted for good |
| `items[].aborted_uploads` | integer |  |
| `items[].complete` | boolean | False when the run stopped before the end of the bucket. The next run carries on from there. |
| `items[].error` | string or null |  |
| `total` | integer |  |

### Whether the bucket has Object Lock, and the default retention it gives every new version {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/object-lock`

Whether the bucket has Object Lock, and the default retention it gives every new version.

``mode`` is ``GOVERNANCE`` or ``COMPLIANCE``, with ``days``, or null for no
default retention. ``years`` repeats ``days`` when it is a whole number of
years.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `enabled` | boolean | Whether the bucket was created with Object Lock |
| `mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | The default retention's mode; null for no default retention |
| `days` | integer or null | How long the default retention keeps each new version, in days |
| `years` | integer or null | ``days`` in years, when it is a whole number of years |
| `bucket_id` | integer |  |

### Change the default retention of a bucket that has Object Lock {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/object-lock`

Change the default retention of a bucket that has Object Lock.

Send a ``mode`` with ``days`` or ``years``, or ``mode`` null to remove the
default. Versions that already exist keep the retention they have. A
compliance default can only be made longer and stays compliance: anything
else answers 409 with the current ``mode`` and ``days``. To shorten or
remove a governance default, set ``confirm`` to the bucket's name, or the
answer is 422. A bucket made without Object Lock answers 409, because
Object Lock can only be chosen when the bucket is made.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | no | The default retention's mode; null removes the default retention |
| `days` | integer or null | no | How long, in days, from 1 to 36500 |
| `years` | integer or null | no | How long, in years, from 1 to 100, instead of days |
| `confirm` | string or null | no | The bucket's name, needed to shorten or remove a governance default |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `enabled` | boolean | Whether the bucket was created with Object Lock |
| `mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | The default retention's mode; null for no default retention |
| `days` | integer or null | How long the default retention keeps each new version, in days |
| `years` | integer or null | ``days`` in years, when it is a whole number of years |
| `bucket_id` | integer |  |

### One page of the bucket under prefix, folders first {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects`

One page of the bucket under ``prefix``, folders first.

A folder is a prefix that more than one key shares, and shows as one entry
with ``is_prefix`` true. Pass ``next_token`` back as ``token`` to read the
next page.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |
| `prefix` | query | string | no | Only keys that start with this |
| `token` | query | string or null | no | ``next_token`` from the page before |
| `max_keys` | query | integer | no | Keys per page, from 1 to 1000 Default: `200`. |
| `flat` | query | boolean | no | List every key under the prefix, with no folders Default: `False`. |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type |
| --- | --- |
| `items` | array of ObjectItem |
| `items[].key` | string |
| `items[].size` | integer or null |
| `items[].last_modified` | string or null |
| `items[].etag` | string or null |
| `items[].is_prefix` | boolean |
| `prefix` | string |
| `next_token` | string or null |

### Delete up to 1000 named objects {#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-o}

`DELETE /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects`

Delete up to 1000 named objects. A key that cannot be deleted is listed in ``errors`` and the others are still deleted.

In a bucket that keeps versions, this adds a delete marker and keeps the
versions. Use the version routes to remove a version for good. Answers 409
when the service is not active.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required |
| --- | --- | --- |
| `keys` | array of string | yes |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type |
| --- | --- |
| `deleted` | integer |
| `errors` | array of object |

### Get object details {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/details`

One version of an object: its size, type, metadata and tags, its retention and legal hold, and the key's versions.

Answers 404 for a key or version that does not exist, or a version that is
a delete marker.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |
| `key` | query | string | yes | The object's key |
| `version_id` | query | string or null | no | A version's ID; the current version when left out |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `key` | string |  |
| `version_id` | string |  |
| `is_latest` | boolean |  |
| `size` | integer |  |
| `content_type` | string or null |  |
| `etag` | string or null |  |
| `last_modified` | string or null |  |
| `metadata` | Metadata | The object's ``x-amz-meta-*`` values |
| `tags` | array of TagOut |  |
| `tags[].key` | string |  |
| `tags[].value` | string |  |
| `retention` | RetentionView or null |  |
| `retention.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` |  |
| `retention.until` | string | When the retention ends, UTC |
| `retention.active` | boolean | False once the date has passed |
| `legal_hold` | boolean |  |
| `object_lock` | boolean | Whether the bucket has Object Lock, so retention and legal holds apply |
| `versioning` | string, one of `off`, `enabled`, `suspended` |  |
| `versions` | array of VersionItem | This key's versions and delete markers, newest first, up to 50 |
| `versions[].key` | string |  |
| `versions[].version_id` | string | The version's id; ``null`` for an object written while versioning was off |
| `versions[].is_latest` | boolean | Whether this is the object's current version |
| `versions[].is_delete_marker` | boolean | A delete marker hides the object; deleting the marker brings it back |
| `versions[].size` | integer or null |  |
| `versions[].last_modified` | string or null |  |
| `versions[].etag` | string or null |  |
| `versions_truncated` | boolean | True when the key has more than 50 |

### Put a legal hold on a version, or take it off {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/legal-hold`

Put a legal hold on a version, or take it off.

While a version has a legal hold nobody can delete it, whatever its
retention says. Answers 409 on a bucket without Object Lock.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes | The object's key |
| `version_id` | string or null | no | The version's id; the current version when left out |
| `on` | boolean | yes | True puts a legal hold on the version; false takes it off |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type |
| --- | --- |
| `key` | string |
| `version_id` | string |
| `legal_hold` | boolean |

### A short-lived URL a browser or app uses directly for one GET, PUT or DELETE of one object {#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obj}

`POST /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/presign`

A short-lived URL a browser or app uses directly for one GET, PUT or DELETE of one object.

Bytes go straight to storage and do not pass through this API. Anyone who
has the URL can use it until it expires, and we count each request made
with it like one signed with the customer's own key. The URL lasts
``expires`` seconds, at most the service's ``presign_max_seconds``. A PUT or
DELETE URL needs an active service; a GET URL works in any status.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes |  |
| `op` | string, one of `get`, `put`, `delete` | yes |  |
| `content_type` | string or null | no |  |
| `expires` | integer or null | no |  |
| `download` | boolean | no |  |
| `version_id` | string or null | no | For get: the version to download, from the versions list. Leave out for the current one |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `url` | string |  |
| `method` | string |  |
| `headers` | Headers |  |
| `expires_in` | integer |  |
| `expires_at` | string |  |
| `version_id` | string or null | The version the URL downloads, when one was asked for |

### Restore object version {#op-post-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obj}

`POST /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/restore`

Make an older version current again by copying it over the current one, with its metadata and tags.

The version it replaces is kept. Answers 409 on a bucket that does not keep
versions, 404 for a version that does not exist, and 422 for a version
larger than 5 GB.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes |  |
| `version_id` | string | yes | The version to copy over the current one |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `ok` | boolean |  |
| `key` | string |  |
| `restored_from` | string |  |
| `version_id` | string | The id of the new current version |

### Give a version a retention, or change the one it has {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/retention`

Give a version a retention, or change the one it has.

Compliance retention can only be made longer and stays compliance: anything
else answers 409 with ``locked_until``. Governance retention can be made
longer freely. To shorten it, or to remove it with ``mode`` null, set
``confirm`` to the object's name after the last ``/``, or the answer is 422.
Removed governance retention ends within a minute. Answers 409 on a bucket
without Object Lock, and 422 for a date less than a minute ahead or more
than 100 years ahead.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes | The object's key |
| `version_id` | string or null | no | The version's id; the current version when left out |
| `mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | no | The retention's mode; null removes governance retention, which then ends within a minute |
| `until` | string (date-time) or null | no | When the retention ends, ISO 8601; at least a minute ahead |
| `confirm` | string or null | no | The object's name after the last ``/``, needed to shorten or remove governance retention |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `key` | string |  |
| `version_id` | string |  |
| `retention` | RetentionView or null |  |
| `retention.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` |  |
| `retention.until` | string | When the retention ends, UTC |
| `retention.active` | boolean | False once the date has passed |

### Delete one version or delete marker for good {#op-delete-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-o}

`DELETE /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/version`

Delete one version or delete marker for good. There is no undo.

A version with a legal hold, or under compliance retention, answers 409; for
compliance, ``locked_until`` says when it can be deleted. A version under
governance retention answers 409 unless ``bypass_governance`` is true and
``confirm`` is the object's name after the last ``/`` (422 when it does not
match). Deleting a delete marker makes the version under it current again.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes |  |
| `version_id` | string | yes | The version or delete marker to remove |
| `bypass_governance` | boolean | no | Delete a version under governance retention anyway |
| `confirm` | string or null | no | The object's name after the last ``/``, needed with ``bypass_governance`` |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `ok` | boolean |  |
| `key` | string |  |
| `version_id` | string |  |
| `delete_marker` | boolean | True when what was removed was a delete marker |

### List object versions {#op-get-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-obje}

`GET /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/objects/versions`

One page of every version and delete marker under ``prefix``, by key and newest first, with the folders under it.

A bucket that never kept versions lists each object once, with
``version_id`` null.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |
| `prefix` | query | string | no | Only keys that start with this |
| `key_marker` | query | string or null | no | ``next_key_marker`` from the page before |
| `version_marker` | query | string or null | no | ``next_version_marker`` from the page before |
| `max_keys` | query | integer | no | Versions and delete markers per page, from 1 to 1000 Default: `100`. |
| `flat` | query | boolean | no | Every key under the prefix, with no folders Default: `False`. |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `items` | array of VersionItem |  |
| `items[].key` | string |  |
| `items[].version_id` | string | The version's id; ``null`` for an object written while versioning was off |
| `items[].is_latest` | boolean | Whether this is the object's current version |
| `items[].is_delete_marker` | boolean | A delete marker hides the object; deleting the marker brings it back |
| `items[].size` | integer or null |  |
| `items[].last_modified` | string or null |  |
| `items[].etag` | string or null |  |
| `prefixes` | array of string | Folders directly under ``prefix``; empty when ``flat`` is true |
| `prefix` | string |  |
| `next_key_marker` | string or null | Pass back as ``key_marker`` for the next page |
| `next_version_marker` | string or null | Pass back as ``version_marker`` for the next page |

### Turn versioning on for a bucket, or suspend it {#op-put-api-v1-orgs-org-slug-portal-object-storage-service-id-buckets-bucket-id-vers}

`PUT /api/v1/orgs/{org_slug}/portal/object-storage/{service_id}/buckets/{bucket_id}/versioning`

Turn versioning on for a bucket, or suspend it.

While versioning is on, every overwrite and delete keeps the version it
replaces, and those versions count toward the GB-months the customer is
billed for. Suspending stops keeping new versions and keeps the ones the
bucket holds. Versioning cannot be turned off once it is on. Answers 409
for ``suspended`` on a bucket with Object Lock, which keeps versioning on,
and when the service is not active.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `service_id` | path | integer | yes | The Object Storage service's ID, from the service list |
| `bucket_id` | path | integer | yes | The bucket's ID, from the service's bucket list |
| `org_slug` | path | string | yes |  |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string, one of `enabled`, `suspended` | yes | ``enabled`` keeps every version of every object; ``suspended`` stops keeping new ones and keeps the versions the bucket holds. Versioning cannot be turned off once it is on |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | integer |  |
| `versioning` | string, one of `off`, `enabled`, `suspended` |  |
| `object_lock` | ObjectLockOut | A bucket's Object Lock and the default retention it gives new versions. |
| `object_lock.enabled` | boolean | Whether the bucket was created with Object Lock |
| `object_lock.mode` | string, one of `GOVERNANCE`, `COMPLIANCE` or null | The default retention's mode; null for no default retention |
| `object_lock.days` | integer or null | How long the default retention keeps each new version, in days |
| `object_lock.years` | integer or null | ``days`` in years, when it is a whole number of years |
