Skip to main content

Creating a bucket

Go to Storage → Buckets and choose Create Bucket. Bucket Name is the only thing you have to fill in; Versioning, Default encryption, Deletion protection and Tags are on the same form.Those extras are applied as separate calls once the bucket exists, so the bucket is created even if one of them fails, and the console tells you which one did.
Bucket names follow the S3 rules, and they are checked in full:
3–63 characters
required
Lowercase letters, digits and hyphens. Must start and end with a letter or digit, must not contain a double hyphen (--), and must not be shaped like an IP address.
A bucket name is unique across the whole region, not just your account. A name another account already holds comes back 409. Creating a bucket you already own is a no-op that succeeds, so a repeated create is safe.
Bucket count is capped by your organization’s buckets quota; exhausting it is also a 409 on create.

Object Lock has to be decided here

Object Lock can only be enabled at creation. There is no call that turns it on later — you would have to create a new bucket and copy the objects across. Enabling it also turns versioning on, because a lock has nothing to hold onto without versions.
PUT /v1/buckets/{bucket}/object-lock updates the default retention rule on a bucket that already has Object Lock enabled. Against a bucket that does not, it is a 409object lock must be enabled at bucket creation.
Turning Object Lock on is API only. It has to ride on the call that creates the bucket, and the console’s Create Bucket form does not send it — the bucket is created without Object Lock, and the follow-up configuration is refused with that same 409. Create the bucket through the API when you need Object Lock.On a bucket that already has it, the console does edit the rule: the Object Lock card on the bucket’s Settings tab carries the Default retention rule, with a Mode and a Retention period.

Pointing an S3 client at it

Set a custom endpoint and sign with your Basaltic access key. Nothing else about the client changes.
The same access keys you use everywhere else. A service account’s long-lived key needs nothing extra; temporary credentials from STS — a role session or a user session — must also carry the session token, and are rejected without it.See authentication for how to obtain each.
Both styles work. Virtual-hosted (https://my-app-assets.objects.sa-saopaulo-1.basaltic.cloud/key) is what most SDKs default to; path-style (https://objects.sa-saopaulo-1.basaltic.cloud/my-app-assets/key) is available through your client’s addressing-style option.
Set region_name to the Basaltic region code. The value is not checked against the region serving the request — it only has to match what your client signed with — so a tool hard-wired to us-east-1 still works. GetBucketLocation reports the real region.
A signed request must be within 15 minutes of the server’s clock, or it is rejected as too skewed. Presigned URLs are supported with an expiry between 1 second and 7 days, and a URL dated in the future beyond the skew tolerance is refused rather than becoming valid later.

What the S3 endpoint serves

The endpoint is verified against a real AWS SDK rather than a specification of our own — if boto3 can do it and gets S3’s error codes back, it works. What is routed today:

Buckets

ListBuckets, CreateBucket, HeadBucket, DeleteBucket, GetBucketLocation, and the ?policy, ?cors, ?lifecycle, ?versioning, ?encryption, ?tagging, ?object-lock and ?acl sub-resources.

Objects

PutObject, GetObject (including range requests), HeadObject, DeleteObject, DeleteObjects, CopyObject, ListObjects, ListObjectsV2, ListObjectVersions, and the ?tagging, ?retention, ?legal-hold and ?acl sub-resources.

Multipart

CreateMultipartUpload, UploadPart, UploadPartCopy, ListParts, ListMultipartUploads, CompleteMultipartUpload, AbortMultipartUpload.

Payload signing

Signed payloads, UNSIGNED-PAYLOAD, and signed aws-chunked streaming uploads. The body is re-hashed as it streams, so a body that does not match what was signed is rejected mid-flight.
Anything outside that list answers NotImplemented. Preflight OPTIONS requests are answered without a signature, because browsers never sign them.

Deleting a bucket

DELETE /v1/buckets/{bucket} does two quite different things depending on whether deletion protection is on:
The bucket must be empty. Any remaining objects, versions or in-flight multipart uploads make it a 409 BucketNotEmpty. An empty bucket is deleted immediately and the quota slot is released.
The Deletion protection card on the bucket’s Settings tab is a switch; turning it on reveals Recovery window (days), and Save applies both.
recovery_days is clamped to 1–30; 0 uses the default of 7 days.