> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tape.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Objects

For applications that think in buckets and named files rather than tracks. A bucket is a tape, and an object is a named track. The name index is rebuilt from chain history ([the objects architecture page](/protocol/architecture/objects) explains how).

Everything here also works from standard S3 tooling through the [S3-compatible gateway](/tools/s3-gateway).

## Put

Writing an object is a named write with a content type. It dispatches by size like any write and gets certified when coded ([writing](/sdks/writing)). Replace is last-write-wins: writing the same name again creates a new track, and listings resolve to the latest.

Options compose: encrypt-on-write and create-bucket-on-first-put bundle into the same call.

<CodeGroup>
  ```rust Rust theme={null}
  client.put_object(&bucket, "photos/cat.jpg", &image_bytes, Some("image/jpeg")).await?;
  client.put_object(&bucket, "photos/cat.jpg", &new_bytes, Some("image/jpeg")).await?; // replaces
  ```
</CodeGroup>

## Get and head

Retrieval by name resolves through a listing, then fetches. Head returns metadata without the bytes: the etag (the track's on-chain commitment), size, content type, and last-modified.

<CodeGroup>
  ```rust Rust theme={null}
  let bytes = client.get_object(&bucket.address(), "photos/cat.jpg").await?;

  let mut file = tokio::fs::File::create("cat.jpg").await?;
  client.get_object_into(&bucket.address(), "photos/cat.jpg", &mut file).await?; // streaming

  let meta = client.head_object(&bucket.address(), "photos/cat.jpg").await?;
  println!("{} {} {}", meta.etag, meta.size, meta.content_type);
  ```
</CodeGroup>

## List

Listings are name-ordered and paginated over a bucket. Each entry carries the name, size, content type, last-modified, and the track address. The query options: `prefix`, `delimiter` for directory-style browsing over the flat namespace, `cursor` for pagination, and `limit`. Naming conventions for folder-like layouts are on the [objects architecture page](/protocol/architecture/objects#names).

<CodeGroup>
  ```rust Rust theme={null}
  let query = ListObjectsQuery::new("photos/").with_delimiter("/").with_limit(100);
  let page = client.list_objects(&bucket.address(), query).await?;
  ```
</CodeGroup>

## Delete

Deletion is an on-chain operation with a Merkle proof, and it frees tape capacity ([tracks](/protocol/architecture/tracks)). Objects inherit their tape's lifetime: when the tape expires, they go with it, and permissionless extension is the way to keep them alive ([tapes](/protocol/architecture/tapes)).

<CodeGroup>
  ```rust Rust theme={null}
  client.delete_object(&bucket, "photos/cat.jpg").await?;
  let page = client.list_objects(&bucket.address(), ListObjectsQuery::new("")).await?; // gone
  ```
</CodeGroup>

## Buckets

Creating a bucket is reserving a tape, and you can bundle that into the first put. Capacity, lifetime, and delegation are tape operations ([tapes](/protocol/architecture/tapes), [managing tapes](/sdks/writing#managing-tapes)).

For S3 tooling: the same buckets serve SigV4 clients through the S3 gateway once the tape delegates to the gateway's key ([S3 gateway](/tools/s3-gateway)).
