Introduction
Oyster is a Web2-friendly object storage service backed by Walrus (decentralized blob storage) and Sui (onchain state). It gives you familiar HTTP and S3 APIs while a decentralized network stores your data.
What are Oyster's core concepts?
Accounts
Every user has an account. Your Oyster administrator creates accounts and issues you an initial API key (Bearer token). With that token you can create additional API keys, manage buckets and blobs, and generate S3-compatible access keys.
API keys
An API key is a Bearer token that authenticates JSON API requests. You
include it in the Authorization header:
Authorization: Bearer <your-api-key>
Oyster shows the plaintext key exactly once, at creation time. Store it securely.
Buckets
Buckets are named containers for your blobs. Bucket names are globally unique and follow S3-style naming rules:
- 3–63 characters long
- Lowercase letters, digits, and hyphens only
- Must start and end with a letter or digit
- No consecutive hyphens
- Cannot look like an IP address (for example,
192.168.1.1)
Blobs
A blob is a binary object stored inside a bucket, identified by a
user-chosen key (like a file path, for example images/photo.png). Blobs are
content-addressed: Oyster stores identical content once, and multiple
keys can reference it.
Key properties of blobs:
- Public reads: anyone can download a blob by bucket name and key, or by its content-addressed blob ID. Reads need no authentication through the JSON API; the S3-compatible API requires AWS Signature Version 4 (SigV4) authentication for every operation, including reads.
- Authenticated writes: uploading, deleting, and listing blobs require a valid API key or S3 credentials.
- Overwrite semantics: uploading to an existing key replaces the blob.
- Reference-counted deletion: deleting a key removes the reference; Oyster removes the underlying data only when no other keys point to it.
- Expiration: blobs share their account's
StoragePoollifetime rather than expiring individually. AStoragePoolis a single onchain Sui object that Oyster creates for each account on its first upload. A background extension service renews each pool before it expires; see Blob Lifecycle for details.
Which APIs does Oyster expose?
Oyster exposes two ways to interact with your data:
JSON API
A RESTful HTTP API under /api/v1/. Use it with curl, any HTTP client, or
the oyster-cli command-line tool (see the Guides for a CLI quick start). Responses are JSON. This API covers
everything: account management, bucket and blob CRUD, S3 access key management,
wallet information, and more. The JSON API Reference
provides full endpoint documentation.
S3-compatible API
An AWS S3-compatible interface that speaks
the same protocol as Amazon S3. Use the AWS CLI, boto3, the AWS SDK for
JavaScript, or any S3-compatible client. Authenticate with S3 access keys
(which you create through the JSON API) using standard AWS Signature Version 4.
The S3 API Reference covers S3-compatible operations and
AWS CLI setup.
Both APIs share the same underlying storage and database. Changes you make through one are immediately visible in the other.
What's next
- Getting Started: set up credentials and make your first API calls.
- JSON API Reference: full endpoint documentation.
- S3 API Reference: S3-compatible operations and AWS CLI setup.
- Guides: CLI quick start, SDK examples, and deeper topics.
Are blob reads public through the S3 API?
Public, unauthenticated reads apply only to the JSON API. The S3-compatible API requires AWS Signature Version 4 (SigV4) authentication for every operation, including reads. To download a blob through an S3 client, sign the request with an S3 access key.
How does a storage pool control blob expiration?
A StoragePool is a single onchain Sui object that Oyster creates for each account. Walrus storage is epoch-scoped, not time-scoped, and the pool's end_epoch defines the lifetime of every blob in the account. Oyster creates the pool lazily on the account's first upload, with POOL_INITIAL_EPOCHS_AHEAD of runway (default 5). Later uploads share the same expiration.
The account exposes the pool's end_epoch as pool_end_epoch. To check remaining runway, compare it with the network's current epoch. Blob responses carry no per-blob expiration.
The background extension worker (oysterd extend) keeps each pool ahead of expiration. As long as the worker runs and the account's wallet has WAL and SUI to spend, your blobs persist indefinitely.