> For clean Markdown of any page, append .md to the page URL. For a complete documentation index, see https://ibee.ai/docs/llms.txt (full text of every page: https://ibee.ai/docs/llms-full.txt). For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://ibee.ai/docs/_mcp/server.

# Using the S3 API

> Which object operations go through the S3-compatible endpoint, which bucket settings go through the IBEE REST API, and what the S3 endpoint does not serve yet.

IBEE Object Storage has two APIs, and they split the work the same way the portal does.

| Do this                                                                                                                                                | With                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| Create, list, delete buckets; public access; lifecycle, CORS, object lock default, event notifications, custom domains; bucket metrics; S3 credentials | **IBEE REST API** (`/v1/object-storage/...`, platform API token) |
| Upload, download, list, copy and delete objects; folders; multipart uploads; presigned URLs; per-object retention and legal hold                       | **S3 API** (S3 endpoint, S3 credential)                          |

This is how Cloudflare R2 and E2E split it too. DigitalOcean and Hetzner push everything to S3; we don't, because a few S3 bucket-configuration calls are not served on our endpoint (see below).

## Credentials

Create an S3 credential with `POST /v1/object-storage/credentials` (or in the portal under **Org → API Tokens → S3**). The response shows the access key, the secret key once, and the endpoint. Scope it to one bucket with `bucket_scope` and `allowed_buckets` when the application needs only that bucket.

## Endpoint and signing

Use signature version 4, path-style addressing, and the region returned on the bucket (`region` on `GET /v1/object-storage/buckets/{bucket_name}`).

```bash
aws configure set default.s3.addressing_style path
aws --endpoint-url https://<s3-endpoint> s3 ls s3://my-bucket/
aws --endpoint-url https://<s3-endpoint> s3 cp ./report.pdf s3://my-bucket/reports/report.pdf
```

Any S3 SDK works the same way: set the endpoint, the region and path-style addressing.

## Served on the S3 endpoint

Object operations: `PutObject`, `GetObject`, `HeadObject`, `DeleteObject`, `DeleteObjects`, `CopyObject`, `ListObjectsV2`, multipart (`CreateMultipartUpload`, `UploadPart`, `CompleteMultipartUpload`, `AbortMultipartUpload`, `ListMultipartUploads`), presigned URLs for any of them. Bucket reads: `ListBuckets`, `HeadBucket`, `GetBucketLocation`.

A folder is an object key that ends with `/`. Emptying a bucket is `ListObjectsV2` plus `DeleteObjects` (`aws s3 rm s3://my-bucket --recursive`).

## Not served on the S3 endpoint

These answer `501 Not Implemented` on the S3 endpoint. Use the REST operation instead, or the portal where no operation exists yet.

| S3 call                                                              | Use instead                                                                      |
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `PutBucketLifecycleConfiguration`, `GetBucketLifecycleConfiguration` | `PUT` / `GET /v1/object-storage/buckets/{bucket_name}/lifecycle`                 |
| `PutBucketCors`, `GetBucketCors`, `DeleteBucketCors`                 | `PUT` / `GET` / `DELETE .../cors`                                                |
| `PutBucketNotificationConfiguration`                                 | `PUT .../notifications`                                                          |
| `PutObjectLockConfiguration`                                         | `PUT .../object-lock` (default retention; lock itself is set at bucket creation) |
| `PutBucketPolicy`, `PutBucketAcl`                                    | `PATCH /v1/object-storage/buckets/{bucket_name}` with `is_public`                |
| `PutObjectRetention`, `PutObjectLegalHold`                           | Portal only for now (Objects → Set Retention, Legal Hold)                        |
| `PutBucketVersioning`                                                | Versioning is turned on with Object Lock at creation                             |

## Related

* [Buckets](/docs/infrastructure/object-storage/buckets)
* [Presigned URLs](/docs/infrastructure/object-storage/objects/presigned-urls)
* [API credentials](/docs/infrastructure/object-storage/api-tokens)