# S3 operations reference

The S3 data-plane client implements the S3 API surface that Lockwell supports. If you have used the AWS SDK, the
operation names and option names will look familiar.

This page lists every operation in one place so you can see the full breadth at a glance. Each operation is available in
the Go, Node, and Java SDKs with matching names.

For the JSON alternative (bearer tokens instead of SigV4, no XML), see the
[native data-plane API](/reference/native-api). For tenant and key management, see the
[Admin API](/reference/admin-api).

## Buckets

| Operation             | Purpose                                         | Key options                     |
| --------------------- | ----------------------------------------------- | ------------------------------- |
| `CreateBucket`        | Create a private bucket                         | Object Lock enabled at creation |
| `HeadBucket`          | Check that a bucket exists and you can reach it |                                 |
| `DeleteBucket`        | Delete an empty bucket                          |                                 |
| `PutBucketVersioning` | Enable or suspend versioning                    | `Enabled`, `Suspended`          |
| `GetBucketVersioning` | Read the versioning state                       |                                 |

Buckets are always private. There is no public-bucket or anonymous-access toggle.

::: info A public-bucket or anonymous-access toggle is a deliberate non-goal. Share objects with a presigned GET URL or
a native signed URL instead. :::

## Objects: write

| Operation       | Purpose                                   | Key options                                                                                     |
| --------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `PutObject`     | Write an object from a buffer or a stream | content type, user metadata, idempotency key, checksum algorithm, SSE-S3, retention, legal hold |
| `CopyObject`    | Server-side copy within or across buckets | metadata directive (COPY or REPLACE), copy-source conditionals, SSE                             |
| `DeleteObject`  | Delete one object or one version          | version id                                                                                      |
| `DeleteObjects` | Delete up to 1000 objects in one request  | quiet mode, per-key errors with partial success                                                 |

`PutObject` accepts a stream, so you can upload an object larger than memory without buffering it. See
[Upload & download](/guide/data-operations).

## Objects: read

| Operation    | Purpose                               | Key options                                                    |
| ------------ | ------------------------------------- | -------------------------------------------------------------- |
| `GetObject`  | Stream an object body                 | byte range, version id, part number, response header overrides |
| `HeadObject` | Read object metadata without the body | byte range, version id, response header overrides              |

## Listing

| Operation              | Purpose                                  | Key options                                                  |
| ---------------------- | ---------------------------------------- | ------------------------------------------------------------ |
| `ListObjectsV2`        | List objects by prefix, token-paged      | prefix, delimiter, start-after, continuation token, max keys |
| `ListObjects`          | List objects, marker-paged (the v1 form) | prefix, delimiter, marker, max keys                          |
| `ListObjectVersions`   | List versions and delete markers         | prefix, delimiter, key marker, version-id marker, max keys   |
| `ListMultipartUploads` | List in-progress multipart uploads       | prefix, delimiter, key marker, upload-id marker, max uploads |
| `ListParts`            | List the parts of one multipart upload   | part-number marker, max parts                                |

Every listing operation has a paginator that follows the continuation tokens for you: `ListObjectsV2Paginator`,
`ListObjectVersionsPaginator`, `ListMultipartUploadsPaginator`, and `ListPartsPaginator`. Each exposes `HasMorePages()`
and `NextPage()`. See [Listing & pagination](/guide/listing-objects).

## Multipart uploads

| Operation                 | Purpose                                             | Key options                        |
| ------------------------- | --------------------------------------------------- | ---------------------------------- |
| `CreateMultipartUpload`   | Start a multipart upload                            | same write options as `PutObject`  |
| `UploadPart`              | Upload one part                                     | per-part checksum                  |
| `UploadPartCopy`          | Fill a part by server-side copy from another object | copy-source range and conditionals |
| `CompleteMultipartUpload` | Assemble the uploaded parts into one object         | idempotency key                    |
| `AbortMultipartUpload`    | Discard an upload and its parts                     |                                    |

See [Multipart uploads](/guide/multipart-uploads) for a full large-file example.

## Tagging

| Operation             | Purpose                          | Key options |
| --------------------- | -------------------------------- | ----------- |
| `PutObjectTagging`    | Replace the tag set on an object | version id  |
| `GetObjectTagging`    | Read the tag set                 | version id  |
| `DeleteObjectTagging` | Remove all tags                  | version id  |

## Versioning

Versioning is controlled with `PutBucketVersioning` and `GetBucketVersioning` (above). Once enabled, every write keeps
the prior version, a delete writes a delete marker, and you can read or delete a specific `versionId`. List versions
with `ListObjectVersions`. See [Versioning](/guide/versioning).

## Object Lock

| Operation            | Purpose                                       | Key options |
| -------------------- | --------------------------------------------- | ----------- |
| `GetObjectRetention` | Read the retention mode and retain-until date | version id  |
| `GetObjectLegalHold` | Read the legal-hold status                    | version id  |

Retention and legal holds are set when you write the object, through the `PutObject` options (retention mode and
retain-until date, legal hold on or off). Object Lock must be enabled when the bucket is created. Governance-mode bypass
is not supported. See [Object Lock](/guide/object-lock).

## Presigned URLs

| Operation          | Purpose                                             | Key options                   |
| ------------------ | --------------------------------------------------- | ----------------------------- |
| `PresignGetObject` | Build a signed GET URL a browser can fetch directly | expiry (capped by the server) |

The Lockwell S3 service accepts query-SigV4 presigned GET, PUT, HEAD, and DELETE requests from compatible external
clients. The first-party Go, Node, and Java S3 clients generate presigned GET, PUT, HEAD, and DELETE URLs. To let a
browser upload directly with a first-party client, use a native signed PUT URL from the
[app kit or native client](/guide/signed-urls).

That is a deliberate split: presigned writes on the S3 surface stay off, and the native signed URL is the supported
upload path.

## Checksums and integrity

Request a checksum on any write with the checksum option, using CRC32, CRC32C, CRC64NVME, SHA-1, or SHA-256. The SDK
computes the digest on the client, the server verifies it, and the value comes back on the response. Multipart uploads
support a checksum per part. See [Checksums & integrity](/guide/checksums).

## Conditional writes and idempotency

The first-party S3 clients support create-only `PutObject` with `If-None-Match: *`. Overwrite-only
`If-Match: <etag>` writes use the native client.

`CopyObject` does support copy-source conditionals (`If-Match`, `If-None-Match`, `If-Modified-Since`,
`If-Unmodified-Since` evaluated against the source object). Set an idempotency key on a write so a retried request is
applied once. See [Conditional writes & idempotency](/guide/conditional-writes).

## Retries

Construct a client with a retry policy. The default policy makes three attempts with exponential backoff and jitter, and
retries idempotent requests (GET, HEAD, DELETE) along with writes that carry an idempotency key. The disabled policy
makes a single attempt. See [Errors & retries](/guide/errors-and-retries).

## Server-side encryption

Objects are encrypted at rest by default with a per-tenant data key. Request the SSE-S3 server-managed mode explicitly
with the encryption option on a write. SSE-KMS is not supported. The S3 wire API supports SSE-C when at-rest encryption
is enabled: callers provide the same AES-256 customer key and MD5 headers on every applicable write, read, copy, and
multipart request. The first-party Go, Node, and Java S3 clients expose typed SSE-C and copy-source SSE-C helpers.

### Reserved metadata isolation

User metadata is lossless, duplicate-preserving, and user-owned. The merged metadata remediation stores it separately
from internal SSE-C and Object Lock state, including historical reserved names such as
`x-amz-meta-lockwell-sse-customer-key-md5`. Caller-controlled metadata cannot manufacture an internal encryption marker;
the same comma/equals/reserved-name round trips are covered through S3, native HTTP, and LNW/1. This does not make SSE-C
available on native transports: use the S3 surface for genuine customer-provided keys.

## What the S3 client does not do

These are deliberate non-goals. They are not roadmap gaps, and the SDK will not expose them:

- Provider-specific POST policies or STS credentials. The typed S3 presigners cover GET, PUT, HEAD, and DELETE;
  the native client provides constrained GET/PUT URLs for browser-direct flows.
- Public or anonymous buckets, public sharing, ACLs.
- SSE-KMS. SSE-C and copy-source SSE-C are available on the S3 wire and through typed first-party SDK helpers.
- IAM, STS, AssumeRole, and bucket policies (use Lockwell access keys and scopes).
- Website hosting, S3 Select, Inventory, Intelligent-Tiering, Object Lambda, S3 Express.
- Event notifications on the S3 client (configure them on the [native client](/guide/webhooks) instead).

For the reasoning behind these boundaries, see the repository's
[final replacement contract](https://github.com/RusticStack/lockwell/blob/main/docs/final-replacement-contract.md).
