Buckets
Buckets are named containers that hold your blobs. Bucket names are globally unique: no two accounts can have a bucket with the same name.
Bucket naming rules
Bucket names must follow these rules:
- 3–63 characters long
- Only lowercase letters, digits, and hyphens (
-) - Must start and end with a letter or digit
- No consecutive hyphens (
--) - Cannot look like an IP address (for example,
192.168.1.1) - Cannot use reserved names:
health,ready,metrics,api
Valid examples: my-bucket, data-2025, images
Invalid examples: My-Bucket (uppercase), a (too short),
-bucket (starts with hyphen), my--bucket (consecutive hyphens)
Set the server URL and API key
In the examples, $OYSTER_URL is the address of your Oyster server, for example http://localhost:3000. Set it without the /api/v1 prefix, because each example appends the full endpoint path. Your operator provides your API key. Export both values before you run the examples:
export OYSTER_URL="http://localhost:3000"
export API_KEY="your-api-key-here"
Create bucket
POST /api/v1/buckets
Request body:
{
"name": "my-bucket"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Globally unique bucket name |
Example:
curl -s -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "my-bucket"}' \
"$OYSTER_URL/api/v1/buckets" | jq
Response (201 Created):
{
"name": "my-bucket",
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2025-01-15T10:30:00Z"
}
| Field | Type | Description |
|---|---|---|
name | string | Bucket name |
account_id | string | UUID of the owning account |
created_at | string | ISO 8601 timestamp |
Errors:
| Status | Condition |
|---|---|
400 | Invalid bucket name (see naming rules above) |
401 | Missing or invalid API key |
409 | Bucket name already exists |
List buckets
GET /api/v1/buckets
Returns a paginated list of buckets owned by your account. Buckets that belong to other accounts are never listed.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | string | None | Opaque cursor from a previous next_cursor |
limit | integer | 20 | Items per page (max: 100) |
Example:
curl -s -H "Authorization: Bearer $API_KEY" \
"$OYSTER_URL/api/v1/buckets?limit=10" | jq
Response (200 OK):
{
"data": [
{
"name": "my-bucket",
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2025-01-15T10:30:00Z"
},
{
"name": "logs-2025",
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2025-01-16T08:00:00Z"
}
],
"next_cursor": null
}
When next_cursor is not null, pass it as the cursor query parameter
to fetch the next page.
Delete bucket
DELETE /api/v1/buckets/{bucket_name}
Deletes a bucket. The bucket must be empty; delete all blobs first.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
bucket_name | string | Name of the bucket to delete |
Example:
curl -s -X DELETE \
-H "Authorization: Bearer $API_KEY" \
"$OYSTER_URL/api/v1/buckets/my-bucket"
Response: 204 No Content
Errors:
| Status | Condition |
|---|---|
401 | Missing or invalid API key |
404 | Bucket not found or not owned by your account |
409 | Bucket is not empty |
Pagination cursors
A non-null next_cursor is an opaque string, for example eyJjcmVhdGVk... (truncated). Do not parse or build cursor values yourself. Copy the value from the response and pass it unchanged as the cursor query parameter, for example $OYSTER_URL/api/v1/buckets?limit=10&cursor=eyJjcmVhdGVk.... When next_cursor is null, there are no more results.